//File codegen.cpp #include "codegen.h" #include "token.h" #include "quad.h" #include "instlist.h" #include "pmglobs.h" #include "qadfiler.h" #include "codfiler.h" #include #include #include void codegenerator::distributeprogname(char* pname) { char fname[STRSIZE]; int len=strlen(pname)-3; strncpy(fname,pname,len); fname[len]='\0'; strcat(fname,".qad"); qf.store(fname); len=strlen(fname)-4; fname[len]='\0'; strcat(fname,".cod"); cf.store(fname); }; void codegenerator::emitallinsts() { instruction inst; instnode* q; headnode* p=ilist.head; while (p!=NULL) { q=p->nextinst; while (q!=NULL) { inst.setopcode(q->opcode); inst.setopnd(q->operand); cf.emitcode(inst); q=q->nextinst; }; p=p->nexthead; }; }; void codegenerator::setaddrmode(int& opco,token& opnd) { //sets appropriate opcodes to frame direct and immediate addressing switch (opnd.getclass()) { case 1: case 4: if (opnd.getvalue()/LEVEL0ADDRSHIFT==0) opco+=5; else opnd.setvalue(opnd.getvalue()%LEVEL0ADDRSHIFT); break; case 2: case 3: opco++; break; default: cout<<"\nError in opnd class of a quadruple!\n"; opnd.show(); exit(1); }; }; void codegenerator::generate() { token temp; quadruple quad; int opcode; int instnum,curinstnum; temp.setclass(tokenclass(0)); instnum=0; boolean endcodegeneration=FALSE; qf.retrievequadfile(); while (!endcodegeneration) { quad=qf.getnextquad(); ilist.createentry(quad); switch (quad.oper) { case assignop: opcode=110; setaddrmode(opcode,quad.opnd1); ilist.enterinst(opcode,quad.opnd1); //LDA temp.setclass(tokenclass(1)); temp.setvalue(quad.result); opcode=160; setaddrmode(opcode,temp); ilist.enterinst(opcode,temp); //STA instnum+=2; break; case get: opcode=520; setaddrmode(opcode,quad.opnd1); ilist.enterinst(opcode,quad.opnd1); //SII instnum+=1; break; case put: opcode=500; setaddrmode(opcode,quad.opnd1); ilist.enterinst(opcode,quad.opnd1); //LIO instnum+=1; break; case addop: case subop: case mulop: case divop: opcode=110; setaddrmode(opcode,quad.opnd2); ilist.enterinst(opcode,quad.opnd2); //LDA switch (quad.oper) { case addop: opcode=210; break; //ADA case subop: opcode=260; break; //SBA case mulop: opcode=310; break; //MLA case divop: opcode=360; break; //DVA }; setaddrmode(opcode,quad.opnd1); ilist.enterinst(opcode,quad.opnd1); temp.setclass(tokenclass(4)); temp.setvalue(quad.result); opcode=160; setaddrmode(opcode,temp); ilist.enterinst(opcode,temp); //STA instnum+=3; break; case eqop: case noteqop: case lessop: case greaterop: case lesseqop: case greateqop: opcode=110; setaddrmode(opcode,quad.opnd2); ilist.enterinst(opcode,quad.opnd2); //LDA opcode=460; setaddrmode(opcode,quad.opnd1); ilist.enterinst(opcode,quad.opnd1); //CPA curinstnum=instnum+2; temp.setclass(tokenclass(2)); temp.setvalue(curinstnum+3); switch (quad.oper) { case eqop: ilist.enterinst(820,temp);break; //JEQ case noteqop: ilist.enterinst(850,temp);break; //JNE case lessop: ilist.enterinst(810,temp);break; //JLT case greaterop:ilist.enterinst(830,temp);break; //JGT case lesseqop: ilist.enterinst(860,temp);break; //JLE case greateqop:ilist.enterinst(840,temp);break; //JGE }; temp.setclass(tokenclass(2)); temp.setvalue(0); ilist.enterinst(111,temp); //LDA# 0 curinstnum=instnum+2+2; temp.setclass(tokenclass(2)); temp.setvalue(curinstnum+2); ilist.enterinst(800,temp); //JMP temp.setclass(tokenclass(2)); temp.setvalue(1); ilist.enterinst(111,temp); //LDA# 1 opcode=160; temp.setclass(tokenclass(4)); temp.setvalue(quad.result); setaddrmode(opcode,temp); ilist.enterinst(opcode,temp); //STA instnum+=7; break; case not: temp.setclass(tokenclass(2)); temp.setvalue(0); ilist.enterinst(111,temp); //LDA# 0 opcode=460; setaddrmode(opcode,quad.opnd1); ilist.enterinst(opcode,quad.opnd1); //CPA curinstnum=instnum+2; temp.setclass(tokenclass(2)); temp.setvalue(curinstnum+2); ilist.enterinst(850,temp); //JNE temp.setclass(tokenclass(2)); temp.setvalue(1); ilist.enterinst(111,temp); //LDA# 1 opcode=160; temp.setclass(tokenclass(4)); temp.setvalue(quad.result); setaddrmode(opcode,temp); ilist.enterinst(opcode,temp); //STA instnum+=5; break; case odd: opcode=110; setaddrmode(opcode,quad.opnd1); ilist.enterinst(opcode,quad.opnd1); //LDA temp.setclass(tokenclass(2)); temp.setvalue(2); ilist.enterinst(411,temp); //MDA# 2 opcode=160; temp.setclass(tokenclass(4)); temp.setvalue(quad.result); setaddrmode(opcode,temp); ilist.enterinst(opcode,temp); //STA instnum+=3; break; case B: if (quad.result!=ilist.quadnumber()+1) { temp.setvalue(0); ilist.enterinst(800,temp); //JMP instnum+=1; }; break; case BF: opcode=110; setaddrmode(opcode,quad.opnd1); ilist.enterinst(opcode,quad.opnd1); //LDA temp.setclass(tokenclass(2)); temp.setvalue(0); ilist.enterinst(461,temp); //CPA# 0 temp.setvalue(quad.result); ilist.enterinst(820,temp); //JEQ instnum+=3; break; case JSR: temp.setvalue(0); ilist.enterinst(870,temp); //JSR instnum+=1; break; case RTN: temp.setvalue(0); ilist.enterinst(900,temp); //RTN instnum+=1; break; case ASP: if (quad.opnd1.getvalue()!=0) { ilist.enterinst(651,quad.opnd1); //ASP instnum+=1; }; break; case FSP: if (quad.opnd1.getvalue()!=0) { ilist.enterinst(661,quad.opnd1); //FSP instnum+=1; }; break; case PSH: opcode=600; setaddrmode(opcode,quad.opnd1); ilist.enterinst(opcode,quad.opnd1); //PSH instnum+=1; break; case POP: opcode=610; temp.setclass(tokenclass(1)); temp.setvalue(quad.result); setaddrmode(opcode,temp); ilist.enterinst(opcode,temp); //POP instnum+=1; break; case haltop: temp.setvalue(0); ilist.enterinst(990,temp); //HLT instnum+=1; endcodegeneration=TRUE; break; default: cout<<"\nUnidentified Quadruple!\n\n"; exit(1); }; }; ilist.repairjumps(); qf.closequadfile(); cf.createcodefile(); emitallinsts(); cf.closecodefile(); };