diff --git a/.gitignore b/.gitignore index 46becad..0f61fde 100644 --- a/.gitignore +++ b/.gitignore @@ -338,4 +338,5 @@ ASALocalRun/ *.d *.d.* *.o +*.lbl make/oscar64 diff --git a/oscar64/Emulator.cpp b/oscar64/Emulator.cpp index 0523507..ee40051 100644 --- a/oscar64/Emulator.cpp +++ b/oscar64/Emulator.cpp @@ -612,14 +612,14 @@ int Emulator::Emulate(int startIP) addr = mMemory[taddr] + 256 * mMemory[taddr + 1]; if (trace & 2) printf("%04x : %04x %02x %02x __ %s ($%02x,x) (A:%02x X:%02x Y:%02x P:%02x S:%02x %02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], mMemory[ip + 1], mRegA, mRegX, mRegY, mRegP, mRegS, taddr, addr); - mCycles[ip] += 5; + mCycles[ip] += 6; break; case ASMIM_INDIRECT_Y: taddr = mMemory[mIP++]; addr = (mMemory[taddr] + 256 * mMemory[taddr + 1] + mRegY) & 0xffff; if (trace & 2) printf("%04x : %04x %02x %02x __ %s ($%02x),y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr); - mCycles[ip] += 4; + mCycles[ip] += 6; break; case ASMIM_RELATIVE: taddr = mMemory[mIP++]; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index c2f6126..46afd1c 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -2980,12 +2980,34 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra ins->mOperator = IA_ADD; ins->mSrc[1].mTemp = nai->mDst.mTemp; ins->mSrc[0].mTemp = cai->mDst.mTemp; - - printf("MADD0\n"); } else if (ai1 && ai1->mCode == IC_CONSTANT) { - printf("MADD1\n"); + InterInstruction* nai = new InterInstruction(); + nai->mCode = IC_BINARY_OPERATOR; + nai->mOperator = IA_MUL; + nai->mSrc[0].mTemp = mi0->mSrc[0].mTemp; + nai->mSrc[0].mType = IT_INT16; + nai->mSrc[1].mTemp = ins->mSrc[1].mTemp; + nai->mSrc[1].mType = IT_INT16; + nai->mDst.mTemp = spareTemps++; + nai->mDst.mType = IT_INT16; + mInstructions.Insert(i, nai); + + ltvalue[nai->mDst.mTemp] = nullptr; + + InterInstruction* cai = new InterInstruction(); + cai->mCode = IC_CONSTANT; + cai->mDst.mTemp = spareTemps++; + cai->mDst.mType = IT_INT16; + cai->mConst.mIntConst = ai1->mConst.mIntConst * mi1->mConst.mIntConst; + mInstructions.Insert(i, cai); + + ltvalue[cai->mDst.mTemp] = nullptr; + + ins->mOperator = IA_ADD; + ins->mSrc[1].mTemp = nai->mDst.mTemp; + ins->mSrc[0].mTemp = cai->mDst.mTemp; } } } @@ -3004,11 +3026,31 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra { if (ai0 && ai0->mCode == IC_CONSTANT) { - printf("ADDADD00\n"); + InterInstruction* cai = new InterInstruction(); + cai->mCode = IC_CONSTANT; + cai->mDst.mTemp = spareTemps++; + cai->mDst.mType = IT_INT16; + cai->mConst.mIntConst = ai0->mConst.mIntConst + mi1->mConst.mIntConst; + mInstructions.Insert(i, cai); + + ltvalue[cai->mDst.mTemp] = nullptr; + + ins->mSrc[1].mTemp = mi0->mSrc[1].mTemp; + ins->mSrc[0].mTemp = cai->mDst.mTemp; } else if (ai1 && ai1->mCode == IC_CONSTANT) { - printf("ADDADD01\n"); + InterInstruction* cai = new InterInstruction(); + cai->mCode = IC_CONSTANT; + cai->mDst.mTemp = spareTemps++; + cai->mDst.mType = IT_INT16; + cai->mConst.mIntConst = ai1->mConst.mIntConst + mi1->mConst.mIntConst; + mInstructions.Insert(i, cai); + + ltvalue[cai->mDst.mTemp] = nullptr; + + ins->mSrc[1].mTemp = mi0->mSrc[0].mTemp; + ins->mSrc[0].mTemp = cai->mDst.mTemp; } } } @@ -3030,12 +3072,20 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra ins->mSrc[1].mTemp = mi1->mSrc[1].mTemp; ins->mSrc[0].mTemp = cai->mDst.mTemp; - - printf("ADDADD10\n"); } else if (ai1 && ai1->mCode == IC_CONSTANT) { - printf("ADDADD11\n"); + InterInstruction* cai = new InterInstruction(); + cai->mCode = IC_CONSTANT; + cai->mDst.mTemp = spareTemps++; + cai->mDst.mType = IT_INT16; + cai->mConst.mIntConst = ai1->mConst.mIntConst + mi0->mConst.mIntConst; + mInstructions.Insert(i, cai); + + ltvalue[cai->mDst.mTemp] = nullptr; + + ins->mSrc[1].mTemp = mi1->mSrc[0].mTemp; + ins->mSrc[0].mTemp = cai->mDst.mTemp; } } } @@ -3068,12 +3118,9 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra ins->mSrc[1].mTemp = nai->mDst.mTemp; ins->mSrc[0].mTemp = li0->mSrc[0].mTemp; - - printf("LADD0 %d %x\n", mIndex, i); } else if (ai1 && ai1->mCode == IC_CONSTANT) { - printf("LADD1\n"); } } else if (li0->mCode == IC_CONSTANT && li1->mCode == IC_LEA) @@ -3092,8 +3139,6 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra ins->mSrc[1].mTemp = li1->mSrc[1].mTemp; ltvalue[cai->mDst.mTemp] = nullptr; - - printf("LEAEA %d %x\n", mIndex, i); } } } diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index f6d5024..f3f8857 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1329,6 +1329,66 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* else mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation"); } + else + mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation"); + } + else if (vr.mType->mType == DT_TYPE_POINTER || vr.mType->mType == DT_TYPE_ARRAY) + { + if (vr.mType->mType == DT_TYPE_POINTER) + vr = Dereference(proc, block, vr); + else + { + vr = Dereference(proc, block, vr, 1); + + Declaration* ptype = new Declaration(exp->mLocation, DT_TYPE_POINTER); + ptype->mBase = vr.mType->mBase; + ptype->mSize = 2; + vr.mType = ptype; + } + + if (vl.mType->IsIntegerType()) + { + InterInstruction* cins = new InterInstruction(); + cins->mCode = IC_CONSTANT; + + if (exp->mToken == TK_ADD) + { + cins->mConst.mIntConst = vr.mType->mBase->mSize; + } + else + mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation"); + + cins->mDst.mType = IT_INT16; + cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType); + block->Append(cins); + + vl = CoerceType(proc, block, vl, TheSignedIntTypeDeclaration); + + InterInstruction* mins = new InterInstruction(); + mins->mCode = IC_BINARY_OPERATOR; + mins->mOperator = IA_MUL; + mins->mSrc[0].mType = IT_INT16; + mins->mSrc[0].mTemp = vl.mTemp; + mins->mSrc[1].mType = IT_INT16; + mins->mSrc[1].mTemp = cins->mDst.mTemp; + mins->mDst.mType = IT_INT16; + mins->mDst.mTemp = proc->AddTemporary(mins->mDst.mType); + block->Append(mins); + + ins->mCode = IC_LEA; + ins->mSrc[1].mMemory = IM_INDIRECT; + ins->mSrc[0].mType = IT_INT16; + ins->mSrc[0].mTemp = mins->mDst.mTemp; + ins->mSrc[1].mType = IT_POINTER; + ins->mSrc[1].mTemp = vr.mTemp; + ins->mDst.mType = IT_POINTER; + ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); + block->Append(ins); + + vl = vr; + } + else + mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation"); } else { diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index c82d8ca..0ae4747 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1388,6 +1388,20 @@ Expression* Parser::ParseAddExpression(void) nexp->mDecType = nexp->mLeft->mDecType; else if (nexp->mRight->mDecType->mType == DT_TYPE_POINTER && nexp->mLeft->mDecType->IsIntegerType()) nexp->mDecType = nexp->mRight->mDecType; + else if (nexp->mLeft->mDecType->mType == DT_TYPE_ARRAY && nexp->mRight->mDecType->IsIntegerType()) + { + Declaration* dec = new Declaration(nexp->mLocation, DT_TYPE_POINTER); + dec->mSize = 2; + dec->mBase = nexp->mLeft->mDecType->mBase; + nexp->mDecType = dec; + } + else if (nexp->mRight->mDecType->mType == DT_TYPE_ARRAY && nexp->mLeft->mDecType->IsIntegerType()) + { + Declaration* dec = new Declaration(nexp->mLocation, DT_TYPE_POINTER); + dec->mSize = 2; + dec->mBase = nexp->mRight->mDecType->mBase; + nexp->mDecType = dec; + } else if (nexp->mLeft->mDecType->mType == DT_TYPE_FLOAT || nexp->mRight->mDecType->mType == DT_TYPE_FLOAT) nexp->mDecType = TheFloatTypeDeclaration; else