From 10bb751449365d62a86c17b8604f0f54bf6ca4a3 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 19 Sep 2021 20:00:36 +0200 Subject: [PATCH] Fix struct over header boundaries --- include/crt.c | 19 ++++++++ include/crt.h | 2 + oscar64/ByteCodeGenerator.cpp | 17 ++++++- oscar64/ByteCodeGenerator.h | 2 + oscar64/Declaration.cpp | 11 ++++- oscar64/InterCodeGenerator.cpp | 81 ++++++++++++++++++++++---------- oscar64/Parser.cpp | 7 ++- oscar64/oscar64.rc | 8 ++-- oscar64setup/oscar64setup.vdproj | 6 +-- 9 files changed, 116 insertions(+), 37 deletions(-) diff --git a/include/crt.c b/include/crt.c index dc72b8b..b1381fd 100644 --- a/include/crt.c +++ b/include/crt.c @@ -1035,6 +1035,25 @@ __asm inp_store_frame_32 #pragma bytecode(BC_STORE_FRAME_32, inp_store_frame_32) +__asm inp_lea_frame +{ + lda (ip), y + tax + iny + clc + lda (ip), y + adc sp + sta $00, x + iny + lda (ip), y + adc sp + 1 + sta $01, x + iny + jmp startup.exec +} + +#pragma bytecode(BC_LEA_FRAME, inp_lea_frame) + __asm inp_op_negate_16 { sec diff --git a/include/crt.h b/include/crt.h index 4157044..836bddc 100644 --- a/include/crt.h +++ b/include/crt.h @@ -61,6 +61,8 @@ enum ByteCode BC_STORE_FRAME_16, BC_STORE_FRAME_32, + BC_LEA_FRAME, + BC_LOAD_ADDR_8, BC_LOAD_ADDR_U8, BC_LOAD_ADDR_I8, diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index c814ca6..135f19c 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -86,7 +86,7 @@ bool ByteCodeInstruction::LoadsRegister(uint32 reg) const return true; if (mCode >= BC_CONST_8 && mCode <= BC_CONST_32) return true; - if (mCode == BC_LEA_ABS || mCode == BC_LEA_LOCAL) + if (mCode == BC_LEA_ABS || mCode == BC_LEA_LOCAL || mCode == BC_LEA_FRAME) return true; } @@ -136,7 +136,7 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const return true; if (mCode >= BC_CONST_8 && mCode <= BC_CONST_32) return true; - if (mCode == BC_LEA_ABS || mCode == BC_LEA_LOCAL) + if (mCode == BC_LEA_ABS || mCode == BC_LEA_LOCAL || mCode == BC_LEA_FRAME) return true; if (mCode >= BC_BINOP_ADDI_16 && mCode <= BC_BINOP_MULI8_16) return true; @@ -302,6 +302,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl break; case BC_LEA_LOCAL: + case BC_LEA_FRAME: block->PutCode(generator, mCode); block->PutByte(mRegister); block->PutWord(uint16(mValue)); @@ -621,6 +622,13 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr bins.mValue = ins->mIntValue + ins->mVarIndex + proc->mLocalSize + 2; mIns.Push(bins); } + else if (ins->mMemory == IM_FRAME) + { + ByteCodeInstruction bins(BC_LEA_FRAME); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + bins.mValue = ins->mVarIndex + ins->mSIntConst[1] + 2; + mIns.Push(bins); + } else if (ins->mMemory == IM_PROCEDURE) { ByteCodeInstruction bins(BC_CONST_16); @@ -3240,6 +3248,11 @@ void ByteCodeProcedure::Disassemble(FILE * file, ByteCodeGenerator * generator, i += 3; break; + case BC_LEA_FRAME: + fprintf(file, "LEA\t%s, %d(SP)", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc), uint16(generator->mMemory[mProgStart + i + 1] + 256 * generator->mMemory[mProgStart + i + 2])); + i += 3; + break; + case BC_STORE_FRAME_8: fprintf(file, "MOVB\t%d(SP), %s", generator->mMemory[mProgStart + i + 1], TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc)); i += 2; diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index 69e4224..4ef44b1 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -50,6 +50,8 @@ enum ByteCode BC_STORE_FRAME_16, BC_STORE_FRAME_32, + BC_LEA_FRAME, + BC_LOAD_ADDR_8, BC_LOAD_ADDR_U8, BC_LOAD_ADDR_I8, diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 56d3209..da05ada 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -405,7 +405,12 @@ bool Declaration::IsSame(const Declaration* dec) const else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID) return true; else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM) - return false; + { + if (mIdent == dec->mIdent) + return true; + else + return false; + } else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY) return mBase->IsSame(dec->mBase); else if (mType == DT_TYPE_FUNCTION) @@ -459,6 +464,10 @@ bool Declaration::CanAssign(const Declaration* fromType) const { return true; } + else if (mBase->mType == DT_TYPE_VOID && fromType->mType == DT_TYPE_FUNCTION) + { + return true; + } } return false; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 43f09bf..d889d8a 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1435,37 +1435,66 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock); - if (vr.mType->mType != DT_TYPE_ARRAY) - vr = Dereference(proc, block, vr); - - if (pdec) + if (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION) { - if (!pdec->mBase->CanAssign(vr.mType)) + if (pdec && !pdec->mBase->CanAssign(vr.mType)) mErrors->Error(texp->mLocation, "Cannot assign incompatible types"); - vr = CoerceType(proc, block, vr, pdec->mBase); - } - else if (vr.mType->IsIntegerType() && vr.mType->mSize < 2) - { - vr = CoerceType(proc, block, vr, TheSignedIntTypeDeclaration); - } - InterInstruction * wins = new InterInstruction(); - wins->mCode = IC_STORE; - wins->mMemory = IM_INDIRECT; - wins->mSType[0] = InterTypeOf(vr.mType);; - wins->mSTemp[0] = vr.mTemp; - wins->mSType[1] = IT_POINTER; - wins->mSTemp[1] = ains->mTTemp; - if (pdec) - wins->mOperandSize = pdec->mSize; - else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY) - wins->mOperandSize = vr.mType->mSize; + vr = Dereference(proc, block, vr, 1); + + if (vr.mReference != 1) + mErrors->Error(exp->mLeft->mLocation, "Not an adressable expression"); + + InterInstruction* cins = new InterInstruction(); + cins->mCode = IC_COPY; + cins->mMemory = IM_INDIRECT; + cins->mSType[0] = IT_POINTER; + cins->mSTemp[0] = vr.mTemp; + cins->mSType[1] = IT_POINTER; + cins->mSTemp[1] = ains->mTTemp; + cins->mOperandSize = vr.mType->mSize; + block->Append(cins); + + atotal += cins->mOperandSize; + } else - wins->mOperandSize = 2; + { + if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION) + vr = Dereference(proc, block, vr, 1); + else + vr = Dereference(proc, block, vr); - block->Append(wins); + if (pdec) + { + if (!pdec->mBase->CanAssign(vr.mType)) + mErrors->Error(texp->mLocation, "Cannot assign incompatible types"); + vr = CoerceType(proc, block, vr, pdec->mBase); + } + else if (vr.mType->IsIntegerType() && vr.mType->mSize < 2) + { + vr = CoerceType(proc, block, vr, TheSignedIntTypeDeclaration); + } + + + InterInstruction* wins = new InterInstruction(); + wins->mCode = IC_STORE; + wins->mMemory = IM_INDIRECT; + wins->mSType[0] = InterTypeOf(vr.mType);; + wins->mSTemp[0] = vr.mTemp; + wins->mSType[1] = IT_POINTER; + wins->mSTemp[1] = ains->mTTemp; + if (pdec) + wins->mOperandSize = pdec->mSize; + else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY) + wins->mOperandSize = vr.mType->mSize; + else + wins->mOperandSize = 2; + + block->Append(wins); + + atotal += wins->mOperandSize; + } - atotal += wins->mOperandSize; if (pdec) pdec = pdec->mNext; } @@ -1541,6 +1570,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (cexp->mAsmInsType != ASMIT_BYTE) { int opcode = AsmInsOpcodes[cexp->mAsmInsType][cexp->mAsmInsMode]; + if (opcode < 0) + mErrors->Error(cexp->mLocation, "Invalid opcode adressing mode"); d[offset++] = opcode; } diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 2b9defe..08ac840 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -40,8 +40,11 @@ Declaration* Parser::ParseStructDeclaration(uint32 flags, DecType dt) } } - dec->mIdent = structName; - dec->mScope = new DeclarationScope(nullptr); + if (!dec->mIdent || !dec->mScope) + { + dec->mIdent = structName; + dec->mScope = new DeclarationScope(nullptr); + } if (mScanner->mToken == TK_OPEN_BRACE) { diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 96f8a7f..98998dc 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,29,0 - PRODUCTVERSION 1,0,29,0 + FILEVERSION 1,0,30,0 + PRODUCTVERSION 1,0,30,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.0.29.0" + VALUE "FileVersion", "1.0.30.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.0.29.0" + VALUE "ProductVersion", "1.0.30.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 01bbf75..fb4fc38 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -512,15 +512,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{F445EC12-D294-4466-A17F-16892657646C}" - "PackageCode" = "8:{C263EE73-C81E-4C63-9EEA-4FD3EA106F58}" + "ProductCode" = "8:{3661BD30-0CEA-48FD-9F79-F3EE87E35F13}" + "PackageCode" = "8:{E524D01A-EAC6-47DD-A7F3-1E088056634C}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.0.29" + "ProductVersion" = "8:1.0.30" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:"