Fix function pointers in struct consts

This commit is contained in:
drmortalwombat 2022-02-05 16:52:54 +01:00
parent 4831950e61
commit 5147ec6bc9
12 changed files with 202 additions and 44 deletions

View File

@ -5783,6 +5783,8 @@ void ByteCodeBasicBlock::BuildPlacement(GrowingArray<ByteCodeBasicBlock*>& place
mTrueJump->BuildPlacement(placement);
else if (mTrueJump->mPlaced)
mFalseJump->BuildPlacement(placement);
else if (mTrueJump == mFalseJump)
mTrueJump->BuildPlacement(placement);
else if (!mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump)
{
mFalseJump->mPlaced = true;

View File

@ -476,6 +476,53 @@ bool Declaration::IsSubType(const Declaration* dec) const
return false;
}
bool Declaration::IsConstSame(const Declaration* dec) const
{
if (this == dec)
return true;
if (mType != dec->mType)
return false;
if (mSize != dec->mSize)
return false;
if ((mFlags & DTF_SIGNED) != (dec->mFlags & DTF_SIGNED))
return false;
if (mType == DT_TYPE_INTEGER)
return true;
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
return true;
else if (mType == DT_TYPE_ENUM)
return mIdent == dec->mIdent;
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
return mBase->IsSame(dec->mBase);
else if (mType == DT_TYPE_STRUCT)
return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize);
else if (mType == DT_TYPE_FUNCTION)
{
if (!mBase->IsSame(dec->mBase))
return false;
Declaration* dl = mParams, * dr = dec->mParams;
while (dl && dr)
{
if (!dl->mBase->IsSame(dr->mBase))
return false;
dl = dl->mNext;
dr = dr->mNext;
}
if (dl || dr)
return false;
if ((mFlags & DTF_VARIADIC) != (dec->mFlags & DTF_VARIADIC))
return false;
return true;
}
return false;
}
bool Declaration::IsSame(const Declaration* dec) const
{
if (this == dec)

View File

@ -186,6 +186,7 @@ public:
bool CanAssign(const Declaration* fromType) const;
bool IsSame(const Declaration* dec) const;
bool IsSubType(const Declaration* dec) const;
bool IsConstSame(const Declaration* dec) const;
bool IsIntegerType(void) const;
bool IsNumericType(void) const;

View File

@ -2920,7 +2920,7 @@ void InterInstruction::Disassemble(FILE* file)
InterCodeBasicBlock::InterCodeBasicBlock(void)
: mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), mDominator(nullptr),
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr)
mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr), mLoopPathBlocks(nullptr)
{
mInPath = false;
mLoopHead = false;
@ -6894,28 +6894,34 @@ void InterCodeBasicBlock::CollectLoopPath(const GrowingArray<InterCodeBasicBlock
{
if (body.IndexOf(this) >= 0)
{
if (mTrueJump && !mTrueJump->mLoopHead)
if (!mLoopPath)
{
mTrueJump->CollectLoopPath(body, path);
if (mFalseJump)
if (mTrueJump && !mTrueJump->mLoopHead)
{
GrowingArray<InterCodeBasicBlock*> fpath(nullptr);
if (!mFalseJump->mLoopHead)
mFalseJump->CollectLoopPath(body, fpath);
int i = 0;
while (i < path.Size())
mTrueJump->CollectLoopPath(body, mLoopPathBlocks);
if (mFalseJump)
{
if (fpath.IndexOf(path[i]) >= 0)
i++;
else
path.Remove(i);
GrowingArray<InterCodeBasicBlock*> fpath(nullptr);
if (!mFalseJump->mLoopHead)
mFalseJump->CollectLoopPath(body, fpath);
int i = 0;
while (i < mLoopPathBlocks.Size())
{
if (fpath.IndexOf(mLoopPathBlocks[i]) >= 0)
i++;
else
mLoopPathBlocks.Remove(i);
}
}
}
mLoopPathBlocks.Insert(0, this);
mLoopPath = true;
}
path.Insert(0, this);
path = mLoopPathBlocks;
}
}
@ -6942,6 +6948,12 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
if (innerLoop)
{
for (int i = 0; i < body.Size(); i++)
{
body[i]->mLoopPath = false;
body[i]->mLoopPathBlocks.SetSize(0);
}
this->CollectLoopPath(body, path);
#if 0
@ -8913,6 +8925,7 @@ void InterCodeProcedure::Close(void)
// Optimize for size
MergeBasicBlocks();
BuildTraces(false);
DisassembleDebug("Merged basic blocks");
}

View File

@ -323,7 +323,7 @@ public:
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
GrowingInstructionArray mInstructions;
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable;
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath;
NumberSet mLocalRequiredTemps, mLocalProvidedTemps;
NumberSet mEntryRequiredTemps, mEntryProvidedTemps;
@ -345,7 +345,7 @@ public:
GrowingIntegerValueRangeArray mEntryValueRange, mTrueValueRange, mFalseValueRange, mLocalValueRange;
GrowingArray<InterCodeBasicBlock*> mEntryBlocks;
GrowingArray<InterCodeBasicBlock*> mEntryBlocks, mLoopPathBlocks;
GrowingInstructionPtrArray mMergeTValues;
ValueSet mMergeValues;

View File

@ -1726,7 +1726,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
dtype = vl.mType;
if (vl.mType->IsIntegerType() || vr.mType->IsIntegerType())
;
else if (!vl.mType->IsSame(vr.mType))
else if ((vl.mType->mType == DT_TYPE_POINTER || vl.mType->mType == DT_TYPE_ARRAY) && (vr.mType->mType == DT_TYPE_POINTER || vr.mType->mType == DT_TYPE_ARRAY))
{
if (!vl.mType->mBase->IsConstSame(vr.mType->mBase))
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible pointer types");
}
else
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible pointer types");
}
else if (!vl.mType->IsNumericType() || !vr.mType->IsNumericType())
@ -3295,18 +3300,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
}
else if (data->mType == DT_CONST_FUNCTION)
{
if (!data->mLinkerObject)
{
InterCodeProcedure* cproc = this->TranslateProcedure(mod, data->mValue, data);
}
LinkerReference ref;
ref.mObject = variable->mLinkerObject;
ref.mOffset = offset;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = data->mLinkerObject;
ref.mRefOffset = 0;
variable->mLinkerObject->AddReference(ref);
assert(false);
}
else if (data->mType == DT_CONST_POINTER)
{
@ -3340,6 +3334,21 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
variable->mLinkerObject->AddReference(ref);
break;
}
case DT_CONST_FUNCTION:
if (!dec->mLinkerObject)
{
InterCodeProcedure* cproc = this->TranslateProcedure(mod, dec->mValue, dec);
}
LinkerReference ref;
ref.mObject = variable->mLinkerObject;
ref.mOffset = offset;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = dec->mLinkerObject;
ref.mRefOffset = 0;
variable->mLinkerObject->AddReference(ref);
break;
case DT_VARIABLE:
{
if (!dec->mLinkerObject)

View File

@ -11857,6 +11857,72 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
j += 4;
i += 7;
}
else if (i + 6 < mIns.Size() &&
mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ABSOLUTE &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ABSOLUTE && mIns[i + 3].mAddress == mIns[i + 1].mAddress &&
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ABSOLUTE &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ABSOLUTE && mIns[i + 6].mAddress == mIns[i + 4].mAddress &&
!(mIns[i + 6].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
{
mIns[j + 0].mType = ASMIT_INC; mIns[j + 0].mMode = ASMIM_ABSOLUTE; mIns[j + 0].mAddress = mIns[i + 1].mAddress; mIns[j + 0].mLinkerObject = mIns[i + 1].mLinkerObject;
mIns[j + 1].mType = ASMIT_BNE; mIns[j + 1].mMode = ASMIM_RELATIVE; mIns[j + 1].mAddress = 3;
mIns[j + 2].mType = ASMIT_INC; mIns[j + 2].mMode = ASMIM_ABSOLUTE; mIns[j + 2].mAddress = mIns[i + 4].mAddress; mIns[j + 2].mLinkerObject = mIns[i + 4].mLinkerObject;
j += 3;
i += 7;
}
else if (i + 6 < mIns.Size() &&
mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ABSOLUTE &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0xff &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ABSOLUTE && mIns[i + 3].mAddress == mIns[i + 1].mAddress &&
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ABSOLUTE &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0xff &&
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ABSOLUTE && mIns[i + 6].mAddress == mIns[i + 4].mAddress &&
!(mIns[i + 6].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
{
mIns[j + 0].mType = ASMIT_LDA; mIns[j + 0].mMode = ASMIM_ABSOLUTE; mIns[j + 0].mAddress = mIns[i + 1].mAddress; mIns[j + 0].mLinkerObject = mIns[i + 1].mLinkerObject;
mIns[j + 1].mType = ASMIT_BNE; mIns[j + 1].mMode = ASMIM_RELATIVE; mIns[j + 1].mAddress = 3;
mIns[j + 2].mType = ASMIT_DEC; mIns[j + 2].mMode = ASMIM_ABSOLUTE; mIns[j + 2].mAddress = mIns[i + 4].mAddress; mIns[j + 2].mLinkerObject = mIns[i + 4].mLinkerObject;
mIns[j + 3].mType = ASMIT_DEC; mIns[j + 3].mMode = ASMIM_ABSOLUTE; mIns[j + 3].mAddress = mIns[j + 0].mAddress; mIns[j + 3].mLinkerObject = mIns[j + 0].mLinkerObject;
j += 4;
i += 7;
}
else if (i + 6 < mIns.Size() &&
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE &&
mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ABSOLUTE && mIns[i + 3].mAddress == mIns[i + 0].mAddress &&
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ABSOLUTE &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ABSOLUTE && mIns[i + 6].mAddress == mIns[i + 4].mAddress &&
!(mIns[i + 6].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
{
mIns[j + 0].mType = ASMIT_INC; mIns[j + 0].mMode = ASMIM_ABSOLUTE; mIns[j + 0].mAddress = mIns[i + 0].mAddress; mIns[j + 0].mLinkerObject = mIns[i + 0].mLinkerObject;
mIns[j + 1].mType = ASMIT_BNE; mIns[j + 1].mMode = ASMIM_RELATIVE; mIns[j + 1].mAddress = 3;
mIns[j + 2].mType = ASMIT_INC; mIns[j + 2].mMode = ASMIM_ABSOLUTE; mIns[j + 2].mAddress = mIns[i + 4].mAddress; mIns[j + 2].mLinkerObject = mIns[i + 4].mLinkerObject;
j += 3;
i += 7;
}
else if (i + 6 < mIns.Size() &&
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE &&
mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0xff &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ABSOLUTE && mIns[i + 3].mAddress == mIns[i + 0].mAddress &&
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ABSOLUTE &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0xff &&
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ABSOLUTE && mIns[i + 6].mAddress == mIns[i + 4].mAddress &&
!(mIns[i + 6].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
{
mIns[j + 0].mType = ASMIT_LDA; mIns[j + 0].mMode = ASMIM_ABSOLUTE; mIns[j + 0].mAddress = mIns[i + 0].mAddress; mIns[j + 0].mLinkerObject = mIns[i + 0].mLinkerObject;
mIns[j + 1].mType = ASMIT_BNE; mIns[j + 1].mMode = ASMIM_RELATIVE; mIns[j + 1].mAddress = 3;
mIns[j + 2].mType = ASMIT_DEC; mIns[j + 2].mMode = ASMIM_ABSOLUTE; mIns[j + 2].mAddress = mIns[i + 4].mAddress; mIns[j + 2].mLinkerObject = mIns[i + 4].mLinkerObject;
mIns[j + 3].mType = ASMIT_DEC; mIns[j + 3].mMode = ASMIM_ABSOLUTE; mIns[j + 3].mAddress = mIns[j + 0].mAddress; mIns[j + 2].mLinkerObject = mIns[j + 0].mLinkerObject;
j += 4;
i += 7;
}
else if (i + 2 < mIns.Size() &&
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 &&
@ -16574,7 +16640,11 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp]));
if (InterTypeSize[ins->mSrc[0].mType] > 1)
block->mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 1));
if (InterTypeSize[ins->mSrc[0].mType] > 2)
{
block->mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 2));
block->mIns.Push(NativeCodeInstruction(ASMIT_ORA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 3));
}
block->Close(CompileBlock(iproc, iblock->mTrueJump), CompileBlock(iproc, iblock->mFalseJump), ASMIT_BNE);
}
return;

View File

@ -867,8 +867,22 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
}
else if (dtype->mType == DT_TYPE_POINTER)
{
if (exp->mDecValue->mType == DT_CONST_ADDRESS || exp->mDecValue->mType == DT_CONST_FUNCTION)
if (exp->mDecValue->mType == DT_CONST_ADDRESS)
;
else if (exp->mDecValue->mType == DT_CONST_FUNCTION)
{
Declaration* ndec = new Declaration(exp->mDecValue->mLocation, DT_CONST_POINTER);
ndec->mValue = exp;
dec = ndec;
Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTANT);
nexp->mDecType = new Declaration(dec->mLocation, DT_TYPE_POINTER);
nexp->mDecType->mBase = exp->mDecType;
nexp->mDecType->mSize = 2;
nexp->mDecType->mFlags |= DTF_DEFINED;
nexp->mDecValue = ndec;
exp = nexp;
}
else
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Illegal pointer constant initializer");
@ -1013,7 +1027,9 @@ Declaration* Parser::ParseDeclaration(bool variable)
if (pdec->mType == DT_CONST_FUNCTION && ndec->mBase->mType == DT_TYPE_FUNCTION)
{
if (!ndec->mBase->IsSame(pdec->mBase))
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Function declaration differs");
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Function declaration differs", ndec->mIdent->mString);
else if (ndec->mFlags & ~pdec->mFlags & (DTF_FASTCALL | DTF_NATIVE))
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Function call type declaration differs", ndec->mIdent->mString);
else
{
//
@ -1040,7 +1056,7 @@ Declaration* Parser::ParseDeclaration(bool variable)
else if (ndec->mBase->mType == DT_TYPE_POINTER && pdec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase))
;
else
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs");
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs", ndec->mIdent->mString);
}
ndec = pdec;
@ -1056,7 +1072,7 @@ Declaration* Parser::ParseDeclaration(bool variable)
pdec->mBase = ndec->mBase;
}
else
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs");
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs", ndec->mIdent->mString);
}
if (!(ndec->mFlags & DTF_EXTERN))

View File

@ -73,7 +73,7 @@ int main2(int argc, const char** argv)
#else
strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.4.80");
strcpy(strProductVersion, "1.4.82");
#ifdef __APPLE__
uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,80,0
PRODUCTVERSION 1,4,80,0
FILEVERSION 1,4,82,0
PRODUCTVERSION 1,4,82,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.4.80.0"
VALUE "FileVersion", "1.4.82.0"
VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.4.80.0"
VALUE "ProductVersion", "1.4.82.0"
END
END
BLOCK "VarFileInfo"

View File

@ -3648,15 +3648,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64"
"ProductCode" = "8:{CDF4A752-EE1A-4826-A688-9C777C33634F}"
"PackageCode" = "8:{8E54BEFF-6BDB-4136-AF7F-5CFFC7A1E100}"
"ProductCode" = "8:{D7EEA6AF-54FD-48A9-80AF-F19CA9A32D0E}"
"PackageCode" = "8:{497B8392-6DB9-4695-A4BC-E7E7CA9DCB8E}"
"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.4.80"
"ProductVersion" = "8:1.4.82"
"Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"

Binary file not shown.