diff --git a/autotest/autotest.bat b/autotest/autotest.bat index 20138b2..dc0ddf5 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -174,6 +174,12 @@ if %errorlevel% neq 0 goto :error ..\release\oscar64 -e -n structoffsettest2.c if %errorlevel% neq 0 goto :error +..\release\oscar64 -e funcvartest.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -n funcvartest.c +if %errorlevel% neq 0 goto :error + exit /b 0 diff --git a/autotest/funcvartest.c b/autotest/funcvartest.c new file mode 100644 index 0000000..01c7018 --- /dev/null +++ b/autotest/funcvartest.c @@ -0,0 +1,72 @@ +#include +#include +#include + + +typedef float (*fop)(float a, float b); + +float fadd(float a, float b) +{ + return a + b; +} + +float fmul(float a, float b) +{ + return a * b; +} + + +struct FNode +{ + FNode * left, * right; + float value; + fop call; +}; + +FNode * root; + +float fevalB(FNode * f) +{ + if (f->call) + return f->call(fevalB(f->left), fevalB(f->right)); + else + return f->value; +} + +float fevalN(FNode * f) +{ + if (f->call) + return f->call(fevalN(f->left), fevalN(f->right)); + else + return f->value; +} + +#pragma native(fevalN) + +FNode * bop(fop call, FNode * left, FNode * right) +{ + FNode * f = (FNode *)malloc(sizeof(FNode)); + f->call = call; + f->left = left; + f->right = right; + return f; +} + +FNode * bc(float value) +{ + FNode * f = (FNode *)malloc(sizeof(FNode)); + f->value = value; + return f; +} + +int main(void) +{ + FNode * tree = bop(fadd, bop(fmul, bc(3), bc(5)), bc(6)); + + printf("Eval %f, %d\n", fevalB(tree), fevalN(tree)); + + assert(fevalB(tree) == 3 * 5 + 6); + assert(fevalN(tree) == 3 * 5 + 6); + + return 0; +} diff --git a/include/string.c b/include/string.c index 7711d77..b11d4c3 100644 --- a/include/string.c +++ b/include/string.c @@ -1,40 +1,31 @@ #include "string.h" -#if 0 -/* +#if 1 + char * strcpy(char * dst, const char * src) { __asm { - ldy #dst - lda (fp), y - sta $1f - iny - lda (fp), y - sta $20 - - ldy #src - lda (fp), y - sta $1b - iny - lda (fp), y - sta $1c + lda dst + sta accu + lda dst + 1 + sta accu + 1 ldy #0 - L1: lda ($1b), y - sta ($1f), y + L1: lda (src), y + sta (dst), y beq W1 iny bne L1 - inc $1c - inc $20 + inc src + 1 + inc dst + 1 bne L1 W1: rts } } -*/ + #else char * strcpy(char * dst, const char * src) { @@ -47,35 +38,21 @@ char * strcpy(char * dst, const char * src) } #endif -#if 0 -/* +#if 1 + int strcmp(const char * ptr1, const char * ptr2) { - __asm + __asm { - ldy #ptr1 - lda (fp), y - sta $1f - iny - lda (fp), y - sta $20 - - ldy #ptr2 - lda (fp), y - sta $1b - iny - lda (fp), y - sta $1c - ldy #0 - L1: lda ($1f), y + L1: lda (ptr1), y beq W1 - cmp ($1b), y + cmp (ptr2), y bne W2 iny bne L1 - inc $1c - inc $20 + inc ptr1 + 1 + inc ptr2 + 1 bne L1 W2: bcs gt lda #$ff @@ -87,14 +64,14 @@ int strcmp(const char * ptr1, const char * ptr2) lda #$00 sta accu + 1 rts - W1: cmp ($1b), y + W1: cmp (ptr2), y bne W2 lda #$00 sta accu sta accu + 1 } } -*/ + #else int strcmp(const char * ptr1, const char * ptr2) { diff --git a/include/string.h b/include/string.h index 5aa4102..71de7d5 100644 --- a/include/string.h +++ b/include/string.h @@ -1,9 +1,9 @@ #ifndef STRING_H #define STRING_H -char * strcpy(char * dst, const char * src); +__fastcall char * strcpy(char * dst, const char * src); -int strcmp(const char * ptr1, const char * ptr2); +__fastcall int strcmp(const char * ptr1, const char * ptr2); int strlen(const char * str); diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 70bcbe9..178152f 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -696,6 +696,13 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr bins.mValue = ins->mConst.mIntConst + ins->mConst.mVarIndex + proc->mLocalSize + 2; mIns.Push(bins); } + else if (ins->mConst.mMemory == IM_FPARAM) + { + ByteCodeInstruction bins(BC_LEA_ABS); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; + bins.mValue = BC_REG_FPARAMS + ins->mConst.mIntConst + ins->mConst.mVarIndex; + mIns.Push(bins); + } else if (ins->mConst.mMemory == IM_FRAME) { ByteCodeInstruction bins(BC_LEA_FRAME); @@ -778,6 +785,12 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegister = BC_REG_ACCU; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction bins(BC_STORE_REG_32); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -834,6 +847,16 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_32); + ains.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_32); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -932,6 +955,12 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegister = BC_REG_ACCU; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction bins(BC_STORE_REG_16); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -986,6 +1015,17 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegisterFinal = ins->mSrc[0].mFinal; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_16); + ains.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + ains.mRegisterFinal = ins->mSrc[0].mFinal; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_16); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -1089,6 +1129,12 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegister = BC_REG_ACCU; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction bins(BC_STORE_REG_8); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -1142,6 +1188,12 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegister = BC_REG_ACCU; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction bins(BC_STORE_REG_16); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -1195,6 +1247,12 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegister = BC_REG_ACCU; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction bins(BC_STORE_REG_32); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -1253,6 +1311,17 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegisterFinal = ins->mSrc[0].mFinal; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_8); + ains.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + ains.mRegisterFinal = ins->mSrc[0].mFinal; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_8); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -1311,6 +1380,17 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegisterFinal = ins->mSrc[0].mFinal; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_16); + ains.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + ains.mRegisterFinal = ins->mSrc[0].mFinal; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_16); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -1369,6 +1449,17 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mRegisterFinal = ins->mSrc[0].mFinal; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_32); + ains.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + ains.mRegisterFinal = ins->mSrc[0].mFinal; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_32); + bins.mRegister = BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) { int index = ins->mSrc[1].mIntConst; @@ -1507,6 +1598,16 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; mIns.Push(bins); } + else if (ins->mSrc[0].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_32); + ains.mRegister = BC_REG_FPARAMS + ins->mSrc[0].mIntConst + ins->mSrc[0].mVarIndex; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; + mIns.Push(bins); + } else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -1570,6 +1671,16 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; mIns.Push(bins); } + else if (ins->mSrc[0].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_16); + ains.mRegister = BC_REG_FPARAMS + ins->mSrc[0].mIntConst + ins->mSrc[0].mVarIndex; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_16); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; + mIns.Push(bins); + } else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -1635,6 +1746,16 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; mIns.Push(bins); } + else if (ins->mSrc[0].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_8); + ains.mRegister = BC_REG_FPARAMS + ins->mSrc[0].mIntConst + ins->mSrc[0].mVarIndex; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_8); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; + mIns.Push(bins); + } else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -1681,6 +1802,16 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; mIns.Push(bins); } + else if (ins->mSrc[0].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_16); + ains.mRegister = BC_REG_FPARAMS + ins->mSrc[0].mIntConst + ins->mSrc[0].mVarIndex; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_16); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; + mIns.Push(bins); + } else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -1727,6 +1858,16 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; mIns.Push(bins); } + else if (ins->mSrc[0].mMemory == IM_FPARAM) + { + ByteCodeInstruction ains(BC_LOAD_REG_32); + ains.mRegister = BC_REG_FPARAMS + ins->mSrc[0].mIntConst + ins->mSrc[0].mVarIndex; + mIns.Push(ains); + + ByteCodeInstruction bins(BC_STORE_REG_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; + mIns.Push(bins); + } else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM) { int index = ins->mSrc[0].mIntConst; @@ -1835,6 +1976,13 @@ void ByteCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const In bins.mValue = ins->mSrc[1].mIntConst; mIns.Push(bins); } + else if (ins->mSrc[1].mMemory == IM_FPARAM) + { + ByteCodeInstruction bins(BC_CONST_16); + bins.mRegister = BC_REG_ACCU; + bins.mValue = BC_REG_FPARAMS + ins->mSrc[1].mIntConst + ins->mSrc[1].mVarIndex; + mIns.Push(bins); + } else if (ins->mSrc[1].mMemory == IM_PROCEDURE) { ByteCodeInstruction bins(BC_CONST_16); @@ -1907,7 +2055,15 @@ void ByteCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInst bins.mLinkerObject = ins->mSrc[0].mLinkerObject; bins.mValue = ins->mSrc[0].mIntConst; for (int i = 1; i < ins->mNumOperands; i++) - ins->mSrc[0].mLinkerObject->mTemporaries[i - 1] = BC_REG_TMP + proc->mTempOffset[ins->mSrc[i].mTemp]; + { + if (ins->mSrc[i].mTemp < 0) + { + if (ins->mSrc[i].mMemory == IM_FPARAM) + ins->mSrc[0].mLinkerObject->mTemporaries[i - 1] = BC_REG_FPARAMS + ins->mSrc[i].mVarIndex + ins->mSrc[i].mIntConst; + } + else + ins->mSrc[0].mLinkerObject->mTemporaries[i - 1] = BC_REG_TMP + proc->mTempOffset[ins->mSrc[i].mTemp]; + } mIns.Push(bins); } diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 459a64e..7d155b8 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -1872,6 +1872,17 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI { case IC_CALL: case IC_CALL_NATIVE: + if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) + { + ins->mSrc[0].mMemory = tvalue[ins->mSrc[0].mTemp]->mConst.mMemory; + ins->mSrc[0].mLinkerObject = tvalue[ins->mSrc[0].mTemp]->mConst.mLinkerObject; + ins->mSrc[0].mVarIndex = tvalue[ins->mSrc[0].mTemp]->mConst.mVarIndex; + ins->mSrc[0].mOperandSize = tvalue[ins->mSrc[0].mTemp]->mConst.mOperandSize; + ins->mSrc[0].mIntConst = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst; + ins->mSrc[0].mTemp = -1; + } + + break; case IC_ASSEMBLER: if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) { @@ -1882,6 +1893,21 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI ins->mSrc[0].mIntConst = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst; ins->mSrc[0].mTemp = -1; } + for (int i = 1; i < ins->mNumOperands; i++) + { + if (ins->mSrc[i].mTemp >= 0 && tvalue[ins->mSrc[i].mTemp]) + { + InterInstruction* lins = tvalue[ins->mSrc[i].mTemp]; + if (lins->mCode == IC_LOAD && lins->mSrc[0].mTemp < 0 && lins->mSrc[0].mMemory == IM_FPARAM) + { + ins->mSrc[i].mMemory = IM_FPARAM; + ins->mSrc[i].mVarIndex = lins->mSrc[0].mVarIndex; + ins->mSrc[i].mIntConst = lins->mSrc[0].mIntConst; + ins->mSrc[i].mOperandSize = lins->mSrc[0].mOperandSize; + ins->mSrc[i].mTemp = -1; + } + } + } break; case IC_LOAD_TEMPORARY: diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index b213998..aa5db74 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -6123,7 +6123,13 @@ void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterIn { for (int i = 1; i < ins->mNumOperands; i++) { - ins->mSrc[0].mLinkerObject->mTemporaries[i - 1] = BC_REG_TMP + proc->mTempOffset[ins->mSrc[i].mTemp]; + if (ins->mSrc[i].mTemp < 0) + { + if (ins->mSrc[i].mMemory == IM_FPARAM) + ins->mSrc[0].mLinkerObject->mTemporaries[i - 1] = BC_REG_FPARAMS + ins->mSrc[i].mVarIndex + ins->mSrc[i].mIntConst; + } + else + ins->mSrc[0].mLinkerObject->mTemporaries[i - 1] = BC_REG_TMP + proc->mTempOffset[ins->mSrc[i].mTemp]; ins->mSrc[0].mLinkerObject->mTempSizes[i - 1] = InterTypeSize[ins->mSrc[i].mType]; } ins->mSrc[0].mLinkerObject->mNumTemporaries = ins->mNumOperands - 1;