diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index eda2337..feb9f83 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -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; diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index a5e1fc9..95694e9 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -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); diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 2179f72..a7426a0 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -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; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 9fd1a5f..c5bdd67 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -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"); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index c75619f..6579259 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -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); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index cd72336..e6eedbd 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -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 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); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 8091e82..3bf7bcf 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -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]; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 0e12052..0f619bf 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -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; diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 16e927b..357a2dd 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -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] == '=') {