Return short simple structs in accu
This commit is contained in:
parent
27d3666285
commit
81e5321bfc
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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] == '=')
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue