Return short simple structs in accu

This commit is contained in:
drmortalwombat 2025-05-23 12:02:12 +02:00
parent 27d3666285
commit 81e5321bfc
9 changed files with 459 additions and 109 deletions

View File

@ -3160,6 +3160,31 @@ bool Declaration::ContainsArray(void) const
return false;
}
bool Declaration::IsShortIntStruct(void) const
{
if (mType == DT_TYPE_STRUCT && mSize <= 4 && !mDestructor && !mCopyConstructor)
{
Declaration* em = mParams;
while (em)
{
if (em->mType == DT_ELEMENT && em->mBase->IsIntegerType() && em->mBits == 0)
em = em->mNext;
else
return false;
}
// if (strcmp(mIdent->mString, "connection")) return false;
return true;
}
return false;
}
bool Declaration::IsComplexStruct(void) const
{
return mType == DT_TYPE_STRUCT && !IsShortIntStruct();
}
bool Declaration::IsSimpleType(void) const
{
return mType == DT_TYPE_INTEGER || mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_ENUM || mType == DT_TYPE_POINTER;

View File

@ -343,6 +343,8 @@ public:
bool IsReference(void) const;
bool IsIndexed(void) const;
bool ContainsArray(void) const;
bool IsShortIntStruct(void) const;
bool IsComplexStruct(void) const;
void SetDefined(void);

View File

@ -481,7 +481,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
fplimit += 256;
}
if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT)
if (procDec->mBase->mBase->IsComplexStruct())
{
if (nbase < numfpzero && nbase + 2 > numfpzero)
nbase = numfpzero;

View File

@ -11416,6 +11416,35 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
}
break;
#endif
#if 1
case IA_SUB:
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[1].mTemp >= 0 && ltvalue[ins->mSrc[1].mTemp] && ins->mSrc[1].mFinal)
{
InterInstruction* pins = ltvalue[ins->mSrc[1].mTemp];
if (pins->mCode == IC_BINARY_OPERATOR && pins->mOperator == IA_ADD)
{
if (pins->mSrc[0].mTemp < 0)
{
ins->mOperator = IA_ADD;
ins->mSrc[1].Forward(pins->mSrc[1]);
pins->mSrc[1].mFinal = false;
ins->mSrc[0].mIntConst = pins->mSrc[0].mIntConst - ins->mSrc[0].mIntConst;
changed = true;
}
else if (pins->mSrc[1].mTemp < 0)
{
ins->mOperator = IA_ADD;
ins->mSrc[1].Forward(pins->mSrc[0]);
pins->mSrc[0].mFinal = false;
ins->mSrc[0].mIntConst = pins->mSrc[1].mIntConst - ins->mSrc[0].mIntConst;
changed = true;
}
}
}
break;
#endif
}
@ -18644,6 +18673,117 @@ bool InterCodeBasicBlock::SingleBlockLoopPointerSplit(int& spareTemps)
return changed;
}
bool InterCodeBasicBlock::Flatten2DLoop(void)
{
return false;
bool changed = false;
if (!mVisited)
{
mVisited = true;
if (mLoopHead && mNumEntries == 2 && !mFalseJump && mTrueJump && mTrueJump->mNumEntries == 1 && !mTrueJump->mFalseJump && mTrueJump->mInstructions.Size() == 1)
{
InterCodeBasicBlock* lblock = mTrueJump->mTrueJump;
if (lblock->mLoopHead && lblock->mNumEntries == 2 && lblock->mTrueJump == lblock)
{
InterCodeBasicBlock* eblock = lblock->mFalseJump;
if (eblock && eblock->mNumEntries == 1 && eblock->mTrueJump == this)
{
int esz = eblock->mInstructions.Size();
if (esz >= 3 &&
eblock->mInstructions[esz - 1]->mCode == IC_BRANCH &&
eblock->mInstructions[esz - 2]->mCode == IC_RELATIONAL_OPERATOR && eblock->mInstructions[esz - 2]->mDst.mTemp == eblock->mInstructions[esz - 1]->mSrc[0].mTemp &&
(eblock->mInstructions[esz - 2]->mOperator == IA_CMPLU || eblock->mInstructions[esz - 2]->mOperator == IA_CMPNE) &&
eblock->mInstructions[esz - 2]->mSrc[0].mTemp < 0 && eblock->mInstructions[esz - 2]->mSrc[1].IsUnsigned() && eblock->mInstructions[esz - 2]->mSrc[1].mRange.mMaxValue <= eblock->mInstructions[esz - 2]->mSrc[0].mIntConst &&
eblock->mInstructions[esz - 3]->mCode == IC_BINARY_OPERATOR && eblock->mInstructions[esz - 3]->mDst.mTemp == eblock->mInstructions[esz - 2]->mSrc[1].mTemp &&
eblock->mInstructions[esz - 3]->mDst.mTemp == eblock->mInstructions[esz - 3]->mSrc[1].mTemp &&
eblock->mInstructions[esz - 3]->mSrc[0].mTemp < 0 && eblock->mInstructions[esz - 3]->mSrc[0].mIntConst == 1)
{
int otemp = eblock->mInstructions[esz - 3]->mDst.mTemp;
int sz = mInstructions.Size();
if (sz == 3 &&
mInstructions[0]->mCode == IC_BINARY_OPERATOR && (mInstructions[0]->mOperator == IA_SHL || mInstructions[0]->mOperator == IA_MUL) &&
mInstructions[0]->mSrc[0].mTemp < 0 && mInstructions[0]->mSrc[1].mTemp == otemp)
{
int64 scale = mInstructions[0]->mSrc[0].mIntConst;
if (mInstructions[0]->mOperator == IA_SHL)
scale = 1LL << scale;
if (mInstructions[1]->mCode == IC_CONSTANT && mInstructions[1]->mConst.mIntConst == 0)
{
int ilz = lblock->mInstructions.Size();
if (ilz >= 3 &&
lblock->mInstructions[ilz - 1]->mCode == IC_BRANCH &&
lblock->mInstructions[ilz - 2]->mCode == IC_RELATIONAL_OPERATOR && lblock->mInstructions[ilz - 2]->mDst.mTemp == lblock->mInstructions[ilz - 1]->mSrc[0].mTemp &&
(lblock->mInstructions[ilz - 2]->mOperator == IA_CMPLU || lblock->mInstructions[ilz - 2]->mOperator == IA_CMPNE) &&
lblock->mInstructions[ilz - 2]->mSrc[0].mTemp < 0 && lblock->mInstructions[ilz - 2]->mSrc[1].IsUnsigned() && lblock->mInstructions[ilz - 2]->mSrc[1].mRange.mMaxValue <= lblock->mInstructions[ilz - 2]->mSrc[0].mIntConst &&
lblock->mInstructions[ilz - 3]->mCode == IC_BINARY_OPERATOR && lblock->mInstructions[ilz - 3]->mDst.mTemp == lblock->mInstructions[ilz - 2]->mSrc[1].mTemp &&
lblock->mInstructions[ilz - 3]->mDst.mTemp == lblock->mInstructions[ilz - 3]->mSrc[1].mTemp &&
lblock->mInstructions[ilz - 3]->mSrc[0].mTemp < 0 && lblock->mInstructions[ilz - 3]->mSrc[0].mIntConst == 1)
{
int itemp = lblock->mInstructions[ilz - 3]->mDst.mTemp;
int64 icount = lblock->mInstructions[ilz - 2]->mSrc[0].mIntConst;
if (itemp == mInstructions[1]->mDst.mTemp && icount == scale &&
!eblock->mEntryRequiredTemps[itemp] &&
!eblock->mFalseJump->mEntryRequiredTemps[otemp])
{
if (lblock->mInstructions[0]->mCode == IC_BINARY_OPERATOR && lblock->mInstructions[0]->mOperator == IA_ADD &&
((lblock->mInstructions[0]->mSrc[0].mTemp == itemp && lblock->mInstructions[0]->mSrc[1].mTemp == mInstructions[0]->mDst.mTemp) ||
(lblock->mInstructions[0]->mSrc[1].mTemp == itemp && lblock->mInstructions[0]->mSrc[0].mTemp == mInstructions[0]->mDst.mTemp)) &&
!IsTempReferencedInRange(2, sz, itemp) &&
!IsTempReferencedInRange(2, sz, otemp) &&
!lblock->IsTempReferencedInRange(1, ilz - 3, itemp) &&
!lblock->IsTempReferencedInRange(1, ilz - 3, otemp) &&
!eblock->IsTempReferencedInRange(0, esz - 3, otemp))
{
// Extend loop range
int64 xcount = eblock->mInstructions[esz - 2]->mSrc->mIntConst * scale;
eblock->mInstructions[esz - 2]->mSrc[0].mIntConst = xcount;
eblock->mInstructions[esz - 2]->mSrc[1].mRange.mMaxValue = xcount;
eblock->mInstructions[esz - 3]->mSrc[1].mRange.mMaxValue = xcount - 1;
eblock->mInstructions[esz - 3]->mDst.mRange.mMaxValue = xcount;
lblock->mInstructions[ilz - 1]->mCode = IC_JUMP; lblock->mInstructions[ilz - 1]->mNumOperands = 0;
lblock->mTrueJump = eblock;
lblock->mFalseJump = nullptr;
lblock->mLoopHead = false;
lblock->mNumEntries = 1;
lblock->mInstructions[0]->mCode = IC_LOAD_TEMPORARY;
lblock->mInstructions[0]->mNumOperands = 1;
lblock->mInstructions[0]->mSrc[0] = eblock->mInstructions[esz - 3]->mSrc[1];
mEntryValueRange[otemp].mMaxValue = xcount - 1;
lblock->mEntryValueRange[otemp].mMaxValue = xcount - 1;
eblock->mEntryValueRange[otemp].mMaxValue = xcount - 1;
changed = true;
printf("oopsie");
}
}
}
}
}
}
}
}
}
if (mTrueJump && mTrueJump->Flatten2DLoop())
changed = true;
if (mFalseJump && mFalseJump->Flatten2DLoop())
changed = true;
}
return changed;
}
bool InterCodeBasicBlock::PostDecLoopOptimization(void)
{
bool changed = false;
@ -23599,7 +23739,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "fill");
CheckFunc = !strcmp(mIdent->mString, "main");
CheckCase = false;
mEntryBlock = mBlocks[0];
@ -24019,6 +24159,19 @@ void InterCodeProcedure::Close(void)
RebuildIntegerRangeSet();
#endif
#if 1
BuildLoopPrefix();
DisassembleDebug("added dominators");
BuildDataFlowSets();
ResetVisited();
mEntryBlock->Flatten2DLoop();
DisassembleDebug("Flatten2DLoop");
#endif
#if 1
BuildLoopPrefix();
DisassembleDebug("added dominators");
@ -24537,6 +24690,7 @@ void InterCodeProcedure::Close(void)
EliminateDoubleLoopCounter();
DisassembleDebug("EliminateDoubleLoopCounter");
ResetVisited();
mEntryBlock->SingleLoopCountZeroCheck();
@ -24544,6 +24698,19 @@ void InterCodeProcedure::Close(void)
PeepholeOptimization();
ResetVisited();
if (mEntryBlock->Flatten2DLoop())
{
DisassembleDebug("Flatten2DLoop");
ConstLoopOptimization();
BuildDataFlowSets();
TempForwarding(false, true);
PeepholeOptimization();
}
MapVariables();
DisassembleDebug("mapped variabled");

View File

@ -637,6 +637,7 @@ public:
bool MoveConditionOutOfLoop(void);
void SingleLoopCountZeroCheck(void);
bool PostDecLoopOptimization(void);
bool Flatten2DLoop(void);
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue, bool loops);
void RemoveUnusedMallocs(void);

View File

@ -4,7 +4,7 @@
InterCodeGenerator::InterCodeGenerator(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker), mCompilerOptions(COPT_DEFAULT)
{
mMainInitBlock = nullptr;
}
InterCodeGenerator::~InterCodeGenerator(void)
@ -12,6 +12,16 @@ InterCodeGenerator::~InterCodeGenerator(void)
}
static inline InterType InterTypeOfSize(int size)
{
if (size <= 1)
return IT_INT8;
else if (size <= 2)
return IT_INT16;
else
return IT_INT32;
}
static inline InterType InterTypeOf(const Declaration* dec)
{
switch (dec->mType)
@ -3945,6 +3955,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION &&
((mCompilerOptions & COPT_OPTIMIZE_INLINE) || (exp->mLeft->mDecValue->mFlags & DTF_FORCE_INLINE)) &&
!(inlineMapper && inlineMapper->mDepth > 10) &&
!(exp->mLeft->mDecValue->mFlags & DTF_PREVENT_INLINE) &&
exp->mType != EX_VCALL;
bool doInline = false, inlineConstexpr = false;
@ -4027,7 +4038,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
Declaration * decResult = nullptr;
GrowingArray<InterInstruction*> defins(nullptr);
if (ftype->mBase->mType == DT_TYPE_STRUCT)
if (ftype->mBase->IsComplexStruct())
{
int ttemp;
if (lrexp)
@ -4311,7 +4322,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
cins->mSrc[0].mType = IT_POINTER;
cins->mSrc[0].mTemp = vl.mTemp;
if (ftype->mBase->mType != DT_TYPE_VOID && ftype->mBase->mType != DT_TYPE_STRUCT)
if (ftype->mBase->IsShortIntStruct())
{
cins->mDst.mType = InterTypeOfSize(ftype->mBase->mSize);
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
}
else if (ftype->mBase->mType != DT_TYPE_VOID && ftype->mBase->mType != DT_TYPE_STRUCT)
{
cins->mDst.mType = InterTypeOf(ftype->mBase);
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
@ -4334,7 +4350,114 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block->Append(xins);
}
if (decResult)
if (ftype->mBase->IsShortIntStruct())
{
int ttemp;
if (lrexp)
{
ttemp = lrexp->mTemp;
decResult = lrexp->mType;
}
else
{
int nindex = proc->mNumLocals++;
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
vdec->mVarIndex = nindex;
vdec->mBase = ftype->mBase;
vdec->mSize = ftype->mBase->mSize;
decResult = vdec;
InterInstruction* vins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
vins->mDst.mType = IT_POINTER;
vins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
vins->mConst.mType = IT_POINTER;
vins->mConst.mMemory = IM_LOCAL;
vins->mConst.mVarIndex = nindex;
vins->mConst.mOperandSize = ftype->mBase->mSize;
block->Append(vins);
ttemp = vins->mDst.mTemp;
}
// Unmarshall result from return value into struct
Declaration* dec = ftype->mBase->mParams;
while (dec)
{
if (dec->mType == DT_ELEMENT)
{
InterInstruction* oins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
oins->mDst.mType = IT_INT16;
oins->mDst.mTemp = proc->AddTemporary(IT_INT16);
oins->mConst.mType = IT_INT16;
oins->mConst.mIntConst = dec->mOffset;
block->Append(oins);
InterInstruction* ains = new InterInstruction(MapLocation(exp, inlineMapper), IC_LEA);
ains->mSrc[1].mMemory = IM_INDIRECT;
ains->mSrc[1].mType = IT_POINTER;
ains->mSrc[1].mTemp = ttemp;
ains->mSrc[0] = oins->mDst;
ains->mDst.mType = IT_POINTER;
ains->mDst.mMemory = IM_INDIRECT;
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
ains->mDst.mOperandSize = dec->mSize;
ains->mNumOperands = 2;
block->Append(ains);
InterInstruction* csins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
csins->mDst.mType = IT_INT8;
csins->mDst.mTemp = proc->AddTemporary(csins->mDst.mType);
csins->mConst.mType = IT_INT8;
csins->mConst.mIntConst = 8 * dec->mOffset;
csins->mNumOperands = 0;
block->Append(csins);
InterInstruction* asins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
asins->mDst.mType = cins->mDst.mType;
asins->mDst.mTemp = proc->AddTemporary(csins->mDst.mType);
asins->mConst.mType = cins->mDst.mType;
asins->mConst.mIntConst = (1ll << 8 * dec->mSize) - 1;
asins->mNumOperands = 0;
block->Append(asins);
InterInstruction* shins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BINARY_OPERATOR);
shins->mOperator = IA_SHR;
shins->mDst.mType = cins->mDst.mType;
shins->mDst.mTemp = proc->AddTemporary(shins->mDst.mType);
shins->mSrc[1] = cins->mDst;
shins->mSrc[0] = csins->mDst;
shins->mNumOperands = 2;
block->Append(shins);
InterInstruction* andins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BINARY_OPERATOR);
andins->mOperator = IA_AND;
andins->mDst.mType = cins->mDst.mType;
andins->mDst.mTemp = proc->AddTemporary(andins->mDst.mType);
andins->mSrc[0] = asins->mDst;
andins->mSrc[1] = shins->mDst;
andins->mNumOperands = 2;
block->Append(andins);
InterInstruction* sins = new InterInstruction(MapLocation(exp, inlineMapper), IC_STORE);
sins->mSrc[0].mTemp = andins->mDst.mTemp;
sins->mSrc[0].mType = InterTypeOf(dec->mBase);
sins->mSrc[1] = ains->mDst;
sins->mNumOperands = 2;
block->Append(sins);
}
dec = dec->mNext;
}
if (lrexp)
return *lrexp;
return ExValue(ftype->mBase, ttemp, 1);
}
else if (decResult)
{
if (lrexp)
return *lrexp;
@ -4548,9 +4671,130 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mNumOperands = 1;
}
}
else if (!inlineMapper && procType->mBase->IsShortIntStruct())
{
vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, gotos, breakBlock, continueBlock, inlineMapper);
if (vr.mType->IsReference())
{
vr.mReference++;
vr.mType = vr.mType->mBase;
}
vr = Dereference(proc, exp, block, inlineMapper, vr, 1);
if (!procType->mBase || procType->mBase->mType == DT_TYPE_VOID)
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Function has void return type");
else if (!procType->mBase->CanAssign(vr.mType))
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Cannot return incompatible type");
else if (vr.mReference != 1)
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Non addressable object");
// Build marshalled struct into single long
InterInstruction* pins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
pins->mDst.mType = InterTypeOfSize(procType->mBase->mSize);
pins->mDst.mTemp = proc->AddTemporary(pins->mDst.mType);
pins->mConst.mType = pins->mDst.mType;
pins->mConst.mIntConst = 0;
block->Append(pins);
Declaration* dec = procType->mBase->mParams;
while (dec)
{
if (dec->mType == DT_ELEMENT)
{
InterInstruction * oins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
oins->mDst.mType = IT_INT16;
oins->mDst.mTemp = proc->AddTemporary(IT_INT16);
oins->mConst.mType = IT_INT16;
oins->mConst.mIntConst = dec->mOffset;
block->Append(oins);
InterInstruction * ains = new InterInstruction(MapLocation(exp, inlineMapper), IC_LEA);
ains->mSrc[1].mMemory = IM_INDIRECT;
ains->mSrc[1].mType = IT_POINTER;
ains->mSrc[1].mTemp = vr.mTemp;
ains->mSrc[0] = oins->mDst;
ains->mDst.mType = IT_POINTER;
ains->mDst.mMemory = IM_INDIRECT;
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
ains->mDst.mOperandSize = dec->mSize;
ains->mNumOperands = 2;
block->Append(ains);
InterInstruction* lins = new InterInstruction(MapLocation(exp, inlineMapper), IC_LOAD);
lins->mSrc[0] = ains->mDst;
lins->mDst.mType = InterTypeOf(dec->mBase);
lins->mDst.mTemp = proc->AddTemporary(lins->mDst.mType);
lins->mNumOperands = 1;
block->Append(lins);
if (pins->mDst.mType == IT_INT32)
{
if (dec->mSize < 4)
{
InterInstruction* xins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONVERSION_OPERATOR);
xins->mOperator = dec->mSize == 1 ? IA_EXT8TO32U : IA_EXT16TO32U;
xins->mSrc[0] = lins->mDst;
xins->mDst.mType = InterTypeOf(dec->mBase);
xins->mDst.mTemp = proc->AddTemporary(pins->mDst.mType);
xins->mNumOperands = 1;
block->Append(xins);
lins = xins;
}
}
else if (pins->mDst.mType == IT_INT16)
{
if (dec->mSize < 2)
{
InterInstruction* xins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONVERSION_OPERATOR);
xins->mOperator = IA_EXT8TO16U;
xins->mSrc[0] = lins->mDst;
xins->mDst.mType = InterTypeOf(dec->mBase);
xins->mDst.mTemp = proc->AddTemporary(pins->mDst.mType);
xins->mNumOperands = 1;
block->Append(xins);
lins = xins;
}
}
InterInstruction* csins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
csins->mDst.mType = IT_INT8;
csins->mDst.mTemp = proc->AddTemporary(csins->mDst.mType);
csins->mConst.mType = IT_INT8;
csins->mConst.mIntConst = 8 * dec->mOffset;
csins->mNumOperands = 0;
block->Append(csins);
InterInstruction* sins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BINARY_OPERATOR);
sins->mOperator = IA_SHL;
sins->mDst.mType = pins->mDst.mType;
sins->mDst.mTemp = proc->AddTemporary(sins->mDst.mType);
sins->mSrc[1] = lins->mDst;
sins->mSrc[0] = csins->mDst;
sins->mNumOperands = 2;
block->Append(sins);
InterInstruction* orins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BINARY_OPERATOR);
orins->mOperator = IA_OR;
orins->mDst.mType = pins->mDst.mType;
orins->mDst.mTemp = proc->AddTemporary(orins->mDst.mType);
orins->mSrc[0] = pins->mDst;
orins->mSrc[1] = sins->mDst;
orins->mNumOperands = 2;
block->Append(orins);
pins = orins;
}
dec = dec->mNext;
}
ins->mCode = IC_RETURN_VALUE;
ins->mSrc[0] = pins->mDst;
ins->mNumOperands = 1;
}
else if (procType->mBase->mType == DT_TYPE_STRUCT)
{
InterInstruction* ains = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
if (inlineMapper)
@ -4620,101 +4864,6 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
bool moving = exp->mLeft->IsRValue() || exp->mLeft->mType == EX_VARIABLE && !(exp->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && exp->mLeft->mDecType->mType != DT_TYPE_REFERENCE;
CopyStruct(proc, exp, block, rvr, vr, inlineMapper, moving);
#if 0
if (procType->mBase->mCopyConstructor)
{
Declaration* ccdec = procType->mBase->mCopyConstructor;
if (ccdec->mBase->mFlags & DTF_FASTCALL)
{
if (!ccdec->mLinkerObject)
this->TranslateProcedure(proc->mModule, ccdec->mValue, ccdec);
InterInstruction* psins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
psins->mDst.mType = IT_POINTER;
psins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
psins->mConst.mVarIndex = 0;
psins->mConst.mIntConst = 0;
psins->mConst.mOperandSize = 2;
if (procType->mFlags & DTF_FASTCALL)
{
psins->mConst.mMemory = IM_FPARAM;
psins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
}
else
psins->mConst.mMemory = IM_PARAM;
block->Append(psins);
InterInstruction* ssins = new InterInstruction(MapLocation(exp, inlineMapper), IC_STORE);
ssins->mSrc[0] = ains->mDst;
ssins->mSrc[1] = psins->mDst;
block->Append(ssins);
InterInstruction* plins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
plins->mDst.mType = IT_POINTER;
plins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
plins->mConst.mVarIndex = 2;
plins->mConst.mIntConst = 0;
plins->mConst.mOperandSize = 2;
if (procType->mFlags & DTF_FASTCALL)
{
plins->mConst.mMemory = IM_FPARAM;
plins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
}
else
plins->mConst.mMemory = IM_PARAM;
block->Append(plins);
InterInstruction* slins = new InterInstruction(MapLocation(exp, inlineMapper), IC_STORE);
slins->mSrc[0].mType = IT_POINTER;
slins->mSrc[0].mTemp = vr.mTemp;
slins->mSrc[0].mMemory = IM_INDIRECT;
slins->mSrc[0].mOperandSize = procType->mBase->mSize;
slins->mSrc[0].mStride = vr.mType->mStripe;
slins->mSrc[1] = plins->mDst;
block->Append(slins);
proc->AddCalledFunction(proc->mModule->mProcedures[ccdec->mVarIndex]);
InterInstruction* pcins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
pcins->mDst.mType = IT_POINTER;
pcins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
pcins->mConst.mType = IT_POINTER;
pcins->mConst.mVarIndex = ccdec->mVarIndex;
pcins->mConst.mIntConst = 0;
pcins->mConst.mOperandSize = 2;
pcins->mConst.mMemory = IM_GLOBAL;
pcins->mConst.mLinkerObject = ccdec->mLinkerObject;
block->Append(pcins);
InterInstruction* cins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CALL);
if (ccdec->mFlags & DTF_NATIVE)
cins->mCode = IC_CALL_NATIVE;
else
cins->mCode = IC_CALL;
cins->mSrc[0] = pcins->mDst;
cins->mNumOperands = 1;
block->Append(cins);
}
}
else
{
InterInstruction* cins = new InterInstruction(MapLocation(exp, inlineMapper), IC_COPY);
cins->mSrc[0].mType = IT_POINTER;
cins->mSrc[0].mTemp = vr.mTemp;
cins->mSrc[0].mMemory = IM_INDIRECT;
cins->mSrc[0].mOperandSize = procType->mBase->mSize;
cins->mSrc[0].mStride = vr.mType->mStripe;
cins->mSrc[1].mOperandSize = procType->mBase->mSize;
cins->mSrc[1].mType = IT_POINTER;
cins->mSrc[1].mTemp = ains->mDst.mTemp;
cins->mSrc[1].mMemory = IM_INDIRECT;
cins->mConst.mOperandSize = procType->mBase->mSize;
block->Append(cins);
}
#endif
}
else
{
@ -6155,7 +6304,12 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
else
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
if (dec->mBase->mBase->IsShortIntStruct())
{
proc->mValueReturn = true;
proc->mReturnType = IT_INT32;
}
else if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
{
proc->mValueReturn = true;
proc->mReturnType = InterTypeOf(dec->mBase->mBase);
@ -6256,7 +6410,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
void InterCodeGenerator::CompleteMainInit(void)
{
if (mErrors->mErrorCount == 0)
if (mErrors->mErrorCount == 0 && mMainInitBlock)
{
InterInstruction* ins = new InterInstruction(mMainInitProc->mLocation, IC_JUMP);
mMainInitBlock->Append(ins);

View File

@ -55261,7 +55261,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mInterProc->mLinkerObject->mNativeProc = this;
CheckFunc = !strcmp(mIdent->mString, "xtime");
CheckFunc = !strcmp(mIdent->mString, "carvedoors");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];

View File

@ -4371,7 +4371,7 @@ Expression* Parser::AddFunctionCallRefReturned(Expression* exp)
rexp = ConcatExpression(rexp, AddFunctionCallRefReturned(pex));
if (pdec->mBase->mType == DT_TYPE_STRUCT && pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT)
if (pdec->mBase->IsComplexStruct() && pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT)
{
Declaration* vdec = AllocTempVar(pex->mDecType);
@ -5340,7 +5340,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
npdec = npdec->mBase;
// Make room for return value pointer on struct return
if (npdec->mBase->mType == DT_TYPE_FUNCTION && npdec->mBase->mBase->mType == DT_TYPE_STRUCT)
if (npdec->mBase->mType == DT_TYPE_FUNCTION && npdec->mBase->mBase->IsComplexStruct())
{
Declaration* pdec = npdec->mBase->mParams;
while (pdec)
@ -10850,7 +10850,7 @@ Expression* Parser::ParseStatement(void)
{
mFunctionType->mBase = mFunctionType->mBase->DeduceAuto(exp->mLeft->mDecType);
if (mFunctionType->mBase->mType == DT_TYPE_STRUCT)
if (mFunctionType->mBase->IsComplexStruct())
{
// Make room for value struct return
Declaration* p = mFunctionType->mParams;
@ -10864,7 +10864,7 @@ Expression* Parser::ParseStatement(void)
exp->mLeft = CoerceExpression(exp->mLeft, mFunctionType->mBase);
}
exp->mLeft = CleanupExpression(exp->mLeft);
if (exp->mLeft->mType == EX_CONSTRUCT && mFunctionType && mFunctionType->mBase && mFunctionType->mBase->mType == DT_TYPE_STRUCT)
if (exp->mLeft->mType == EX_CONSTRUCT && mFunctionType && mFunctionType->mBase && mFunctionType->mBase->IsComplexStruct())
{
Expression* cexp = exp->mLeft->mLeft->mLeft;

View File

@ -184,6 +184,7 @@ int main2(int argc, const char** argv)
else if (arg[1] == 'r' && arg[2] == 't' && arg[3] == '=')
{
strcpy_s(crtPath, arg + 4);
customCRT = true;
}
else if (arg[1] == 'd' && arg[2] == '6' && arg[3] == '4' && arg[4] == '=')
{