diff --git a/include/crt.c b/include/crt.c index 2703bb5..c0d7fb1 100644 --- a/include/crt.c +++ b/include/crt.c @@ -526,6 +526,8 @@ __asm inp_exit { lda #$4c sta $54 + lda #0 + sta $13 rts } diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 6650d06..ed1c898 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -61,6 +61,7 @@ static const uint32 DTF_UPPER_BYTE = 0x00000400; static const uint32 DTF_LOWER_BYTE = 0x00000800; static const uint32 DTF_SECTION_START = 0x00001000; static const uint32 DTF_SECTION_END = 0x00002000; +static const uint32 DTF_FASTCALL = 0x00004000; static const uint32 DTF_INLINE = 0x00008000; class Declaration; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index c4d01c0..4d4fc4e 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -350,7 +350,7 @@ static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* if (lmem == IM_LOCAL) return aliasedLocals[lvindex]; - else if (lmem == IM_PARAM) + else if (lmem == IM_PARAM || lmem == IM_FPARAM) return aliasedParams[lvindex]; } @@ -1097,14 +1097,14 @@ void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable, Gro { if (mDst.mType == IT_POINTER && mMemory == IM_LOCAL) localTable[mDst.mTemp] = mVarIndex; - else if (mDst.mType == IT_POINTER && mMemory == IM_PARAM) + else if (mDst.mType == IT_POINTER && (mMemory == IM_PARAM || mMemory == IM_FPARAM)) paramTable[mDst.mTemp] = mVarIndex; } else if (mCode == IC_LEA) { if (mMemory == IM_LOCAL) localTable[mDst.mTemp] = localTable[mSrc[1].mTemp]; - else if (mMemory == IM_PARAM) + else if (mMemory == IM_PARAM || mMemory == IM_FPARAM) paramTable[mDst.mTemp] = paramTable[mSrc[1].mTemp]; } else if (mCode == IC_LOAD_TEMPORARY) @@ -1490,7 +1490,7 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum else complexLocals += mVarIndex; } - else if (mMemory == IM_PARAM && mSrc[0].mTemp < 0) + else if ((mMemory == IM_PARAM || mMemory == IM_FPARAM) && mSrc[0].mTemp < 0) { if (paramTypes[mVarIndex] == IT_NONE || paramTypes[mVarIndex] == mDst.mType) { @@ -1512,7 +1512,7 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum else complexLocals += mVarIndex; } - else if (mMemory == IM_PARAM && mSrc[1].mTemp < 0) + else if ((mMemory == IM_PARAM || mMemory == IM_FPARAM) && mSrc[1].mTemp < 0) { if (paramTypes[mVarIndex] == IT_NONE || paramTypes[mVarIndex] == mSrc[0].mType) { @@ -1526,13 +1526,13 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum case IC_LEA: if (mMemory == IM_LOCAL && mSrc[1].mTemp < 0) complexLocals += mVarIndex; - else if (mMemory == IM_PARAM && mSrc[1].mTemp < 0) + else if ((mMemory == IM_PARAM || mMemory == IM_FPARAM) && mSrc[1].mTemp < 0) complexParams += mVarIndex; break; case IC_CONSTANT: if (mDst.mType == IT_POINTER && mMemory == IM_LOCAL) complexLocals += mVarIndex; - else if (mDst.mType == IT_POINTER && mMemory == IM_PARAM) + else if (mDst.mType == IT_POINTER && (mMemory == IM_PARAM || mMemory == IM_FPARAM)) complexParams += mVarIndex; break; } @@ -1579,7 +1579,7 @@ void InterInstruction::Disassemble(FILE* file) { if (this->mCode != IC_NONE) { - static char memchars[] = "NPLGFPITA"; + static char memchars[] = "NPLGFPITAZ"; fprintf(file, "\t"); switch (this->mCode) @@ -3285,7 +3285,7 @@ static bool CanBypassStore(const InterInstruction * sins, const InterInstruction { if (sins->mMemory == IM_LOCAL) { - if (bins->mMemory == IM_PARAM || bins->mMemory == IM_GLOBAL) + if (bins->mMemory == IM_PARAM || bins->mMemory == IM_GLOBAL || bins->mMemory == IM_FPARAM) ; else if (bins->mMemory == IM_LOCAL) { diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index ba01b1f..27059fc 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -60,7 +60,8 @@ enum InterMemory IM_PROCEDURE, IM_INDIRECT, IM_TEMPORARY, - IM_ABSOLUTE + IM_ABSOLUTE, + IM_FPARAM, }; enum InterOperator diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 2d17224..6947ba7 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -758,6 +758,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mMemory = IM_LOCAL; ins->mVarIndex = inlineMapper->mParams[ins->mVarIndex]; } + else if (procType->mFlags & DTF_FASTCALL) + ins->mMemory = IM_FPARAM; else ins->mMemory = IM_PARAM; if (dec->mBase->mType == DT_TYPE_ARRAY) @@ -1739,18 +1741,26 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* int atotal = 0; - int findex = block->mInstructions.Size(); InterCodeBasicBlock* fblock = block; - InterInstruction * fins = new InterInstruction(); - fins->mCode = IC_PUSH_FRAME; - fins->mIntValue = atotal; - block->Append(fins); - - Declaration * ftype = vl.mType; + Declaration* ftype = vl.mType; if (ftype->mType == DT_TYPE_POINTER) ftype = ftype->mBase; + InterInstruction* fins = nullptr; + + if (ftype->mFlags & DTF_FASTCALL) + { + + } + else + { + fins = new InterInstruction(); + fins->mCode = IC_PUSH_FRAME; + fins->mIntValue = atotal; + block->Append(fins); + } + if (exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION) proc->AddCalledFunction(proc->mModule->mProcedures[exp->mLeft->mDecValue->mVarIndex]); else @@ -1764,7 +1774,6 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ains->mCode = IC_CONSTANT; ains->mDst.mType = IT_POINTER; ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType); - ains->mMemory = IM_FRAME; if (pdec) { ains->mVarIndex = pdec->mVarIndex; @@ -1784,6 +1793,15 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* { mErrors->Error(pex->mLocation, EERR_WRONG_PARAMETER, "Too many arguments for function call"); } + + if (ftype->mFlags & DTF_FASTCALL) + { + ains->mMemory = IM_FPARAM; + ains->mIntValue = 0; + } + else + ains->mMemory = IM_FRAME; + block->Append(ains); Expression* texp; @@ -1888,12 +1906,20 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* block->Append(cins); - fblock->mInstructions[findex]->mIntValue = atotal; - InterInstruction * xins = new InterInstruction(); - xins->mCode = IC_POP_FRAME; - xins->mIntValue = atotal; - block->Append(xins); + if (ftype->mFlags & DTF_FASTCALL) + { + + } + else + { + fins->mIntValue = atotal; + + InterInstruction* xins = new InterInstruction(); + xins->mCode = IC_POP_FRAME; + xins->mIntValue = atotal; + block->Append(xins); + } return ExValue(ftype->mBase, cins->mDst.mTemp); } @@ -1939,7 +1965,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* Declaration* vdec = refvars[i]; if (vdec->mType == DT_ARGUMENT) { - vins->mMemory = IM_PARAM; + if (procType->mFlags & DTF_FASTCALL) + vins->mMemory = IM_FPARAM; + else + vins->mMemory = IM_PARAM; vins->mOperandSize = vdec->mSize; vins->mIntValue = vdec->mOffset; vins->mVarIndex = vdec->mVarIndex; @@ -2698,6 +2727,13 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod if (dec->mFlags & DTF_NATIVE) proc->mNativeProcedure = true; + if (dec->mBase->mFlags & DTF_FASTCALL) + { + dec->mLinkerObject->mNumTemporaries = 1; + dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS; + dec->mLinkerObject->mTempSizes[0] = 8; + } + InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock(); proc->Append(entryBlock); diff --git a/oscar64/MachineTypes.h b/oscar64/MachineTypes.h index 027c267..af68dd2 100644 --- a/oscar64/MachineTypes.h +++ b/oscar64/MachineTypes.h @@ -82,6 +82,8 @@ inline int sprintf_s(char* buffer, int size, const char* format, ...) #endif static const uint8 BC_REG_WORK = 0x03; +static const uint8 BC_REG_FPARAMS = 0x0d; + static const uint8 BC_REG_IP = 0x19; static const uint8 BC_REG_ACCU = 0x1b; static const uint8 BC_REG_ADDR = 0x1f; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index a907813..c8c68b8 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -2177,6 +2177,13 @@ void NativeCodeBasicBlock::LoadConstantToReg(InterCodeProcedure * proc, const In mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mIntValue >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, BC_REG_FPARAMS + ins->mVarIndex + ins->mIntValue)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mIntValue; @@ -2288,6 +2295,17 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 3)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2363,6 +2381,17 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 3)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2466,6 +2495,13 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 1)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2512,6 +2548,13 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 1)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2589,6 +2632,11 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2629,6 +2677,13 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 1)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2683,6 +2738,17 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 16) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 3)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2740,6 +2806,11 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2780,6 +2851,13 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 1)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2835,6 +2913,17 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[1].mIntConst + 3)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -2984,6 +3073,10 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, rins->mSrc[0].mIntConst)); } + else if (rins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + rins->mVarIndex + rins->mSrc[0].mIntConst)); + } else if (rins->mMemory == IM_LOCAL || rins->mMemory == IM_PARAM) { int index = rins->mSrc[0].mIntConst; @@ -3018,6 +3111,10 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI { mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, wins->mSrc[1].mIntConst)); } + else if (wins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + wins->mVarIndex + wins->mSrc[1].mIntConst)); + } else if (wins->mMemory == IM_LOCAL || wins->mMemory == IM_PARAM) { int index = wins->mSrc[1].mIntConst; @@ -3124,6 +3221,17 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -3204,6 +3312,22 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI if (ainsh) mIns.Push(*ainsh); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst)); + if (ainsl) + { + if (ainsl->mType == ASMIT_ADC) + mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + else if (ainsl->mType == ASMIT_SBC) + mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); + mIns.Push(*ainsl); + } + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst + 1)); + if (ainsh) mIns.Push(*ainsh); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -3274,6 +3398,10 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -3340,6 +3468,22 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI if (ainsh) mIns.Push(*ainsh); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst)); + if (ainsl) + { + if (ainsl->mType == ASMIT_ADC) + mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + else if (ainsl->mType == ASMIT_SBC) + mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); + mIns.Push(*ainsl); + } + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst + 1)); + if (ainsh) mIns.Push(*ainsh); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -3392,6 +3536,17 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); + } else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -5865,6 +6020,15 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1)); } + else if (ins->mMemory == IM_FPARAM) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, BC_REG_FPARAMS + ins->mVarIndex + ins->mSrc[0].mIntConst)); + mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1)); + } } else { diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index f8cfcf6..29a19b2 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -680,7 +680,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype) Declaration* Parser::ParseDeclaration(bool variable) { bool definingType = false; - uint32 storageFlags = 0; + uint32 storageFlags = 0, typeFlags = 0; if (mScanner->mToken == TK_TYPEDEF) { @@ -688,22 +688,32 @@ Declaration* Parser::ParseDeclaration(bool variable) variable = false; mScanner->NextToken(); } - else if (mScanner->mToken == TK_STATIC) + else + + if (mScanner->mToken == TK_STATIC) { storageFlags |= DTF_STATIC; mScanner->NextToken(); } - else if (mScanner->mToken == TK_EXTERN) + + if (mScanner->mToken == TK_EXTERN) { storageFlags |= DTF_EXTERN; mScanner->NextToken(); } - else if (mScanner->mToken == TK_INLINE) + + if (mScanner->mToken == TK_INLINE) { storageFlags |= DTF_INLINE; mScanner->NextToken(); } + if (mScanner->mToken == TK_FASTCALL) + { + typeFlags |= DTF_FASTCALL; + mScanner->NextToken(); + } + Declaration* bdec = ParseBaseTypeDeclaration(0); Declaration* rdec = nullptr, * ldec = nullptr; @@ -734,6 +744,7 @@ Declaration* Parser::ParseDeclaration(bool variable) { ndec->mType = DT_CONST_FUNCTION; ndec->mSection = mCodeSection; + ndec->mBase->mFlags |= typeFlags; } if (ndec->mIdent) diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index 718bc1c..d5a2ca9 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -46,6 +46,7 @@ const char* TokenNames[] = { "'static'", "'extern'", "'inline'", + "'__fastcall'", "__asm", @@ -1151,6 +1152,8 @@ void Scanner::NextRawToken(void) mToken = TK_EXTERN; else if (!strcmp(tkident, "inline")) mToken = TK_INLINE; + else if (!strcmp(tkident, "__fastcall")) + mToken = TK_FASTCALL; else if (!strcmp(tkident, "__asm")) mToken = TK_ASM; else diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index 32bcf88..c33cecd 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -45,6 +45,7 @@ enum Token TK_STATIC, TK_EXTERN, TK_INLINE, + TK_FASTCALL, TK_ASM,