/* Generate code for a Statement from an intermediate-code form */ void genc(TOKEN code) { TOKEN tok, lhs, rhs; int reg, offs; SYMBOL sym; if (DEBUGGEN) { printf("genc\n"); dbugprinttok(code); }; if ( code->tokentype != OPERATOR ) { printf("Bad code token"); dbugprinttok(code); }; switch ( code->whichval ) { case PROGNOP: tok = code->operands; while ( tok != NULL ) { genc(tok); tok = tok->link; }; break; case ASSIGNOP: /* Trivial version: handles I := e */ lhs = code->operands; rhs = lhs->link; reg = genarith(rhs); /* generate rhs into a register */ sym = lhs->symentry; /* assumes lhs is a simple var */ offs = sym->offset - stkframesize; /* net offset of the var */ switch (code->datatype) /* store value into lhs */ { case INTEGER: asmst(MOVL, reg, offs, lhs->stringval); break; /* ... */ }; break; }; }
/* Generate code for a Statement from an intermediate-code form */ void genc(TOKEN code) { TOKEN tok, lhs, rhs; int reg, reg2, offs; int thenlbl, elselbl; SYMBOL sym; if (DEBUGGEN) { printf("genc\n"); dbugprinttok(code); }; if ( code->tokentype != OPERATOR ) { printf("Bad code token"); dbugprinttok(code); }; clearreg(); switch ( code->whichval ) { case PROGNOP: tok = code->operands; while ( tok != NULL ) { genc(tok); tok = tok->link; }; break; case ASSIGNOP: lhs = code->operands; if(lhs->whichval == AREFOP) { rhs = lhs->link; reg = genarith(rhs); /* generate rhs into a register */ reg2 = genaref(lhs, reg); //asmst(MOVL, reg, offs, lhs->stringval); } else { sym = lhs->symentry; /* assumes lhs is a simple var */ offs = sym->offset - stkframesize; /* net offset of the var */ rhs = lhs->link; reg = genarith(rhs); /* generate rhs into a register */ switch (code->datatype) /* store value into lhs */ { case INTEGER: asmst(MOVL, reg, offs, lhs->stringval); break; case REAL: asmst(MOVSD, reg, offs, lhs->stringval); break; case STRINGTYPE: asmst(MOVL, reg, offs, lhs->stringval); break; case BOOLETYPE: asmst(MOVL, reg, offs, lhs->stringval); break; case POINTER: asmst(MOVQ, reg, offs, lhs->stringval); break; }; } break; case GOTOOP: asmjump(JMP, code->operands->intval); break; case LABELOP: asmlabel(code->operands->intval); break; case IFOP: thenlbl = nextlabel++; elselbl = nextlabel++; genarith(code->operands); //genarith on condition asmjump(broptbl[code->operands->whichval], thenlbl); //branch to then if(((code->operands)->link)->link != NULL) //gen else genc(((code->operands)->link)->link); asmjump(JMP, elselbl); asmlabel(thenlbl); genc((code->operands)->link); //genthen asmlabel(elselbl); break; case FUNCALLOP: genfun(code); break; }; }
/* Generate code for a Statement from an intermediate-code form */ void genc(TOKEN code) { TOKEN tok, lhs, rhs; int reg, reg2, offs, jmpval, loop1, loop2; SYMBOL sym, lsym, rsym; if (DEBUGGEN) { printf("genc\n"); dbugprinttok(code); }; if ( code->tokentype != OPERATOR ) { printf("Bad code token"); dbugprinttok(code); }; // This switch statement will determine how to handle the token based on its operator value switch ( code->whichval ) { case PROGNOP: tok = code->operands; while ( tok != NULL ) { genc(tok); tok = tok->link; }; break; case ASSIGNOP: /* Trivial version: handles I := e */ lhs = code->operands; rhs = lhs->link; reg = genarith(rhs); /* generate rhs into a register */ if(rhs != NULL) rsym = rhs->symentry; if(lhs->tokentype == OPERATOR & lhs->whichval == AREFOP) { if(lhs->operands->tokentype != OPERATOR & lhs->operands->whichval != POINTEROP) { if(lhs->operands->link->tokentype == NUMBERTOK) { lsym = lhs->operands->symentry; reg2 = getreg(WORD); asmimmed(MOVL, lhs->operands->link->intval, reg2); asmop(CLTQ); if(reg < 8 & reg2 < 8) { asmstrr(MOVL, reg, lsym->offset - stkframesize, reg2, lhs->operands->stringval); } else { asmstrr(MOVSD, reg, lsym->offset - stkframesize, reg2, lhs->operands->stringval); } break; } else { reg2 = genarith(lhs->operands->link); asmop(CLTQ); lsym = lhs->operands->symentry; if(reg < 8 & reg2 < 8) { asmstrr(MOVL, reg, lsym->offset - stkframesize, reg2, lhs->operands->stringval); } else { asmstrr(MOVSD, reg, lsym->offset - stkframesize, reg2, lhs->operands->stringval); } break; } } reg2 = genarith(lhs->operands); offs = lhs->operands->link->intval; if(rsym != NULL) { if(rsym->datatype->kind == POINTERSYM) asmstr(MOVQ, reg, offs, reg2, "^. "); else { if (reg < 8 & reg2 < 8) asmstr(MOVL, reg, offs, reg2, "^. "); else asmstr(MOVSD, reg, offs, reg2, "^. "); } } else { if (reg < 8 & reg2 < 8) asmstr(MOVL, reg, offs, reg2, "^. "); else asmstr(MOVSD, reg, offs, reg2, "^. "); } unused(reg); break; } else { lsym = lhs->symentry; /* assumes lhs is a simple var */ offs = lsym->offset - stkframesize; /* net offset of the var */ } if(lsym->datatype->kind == POINTERSYM) { asmst(MOVQ, reg, offs, lhs->stringval); } else { switch (code->datatype) /* store value into lhs */ { case INTEGER: asmst(MOVL, reg, offs, lhs->stringval); break; case REAL: asmst(MOVSD, reg, offs, lhs->stringval); break; } } unused(reg); break; case PLUSOP: lhs = code->operands; rhs = lhs->link; lsym = lhs->symentry; rsym = rhs->symentry; if(lsym != NULL & lhs->tokentype != NUMBERTOK) asmldr(MOVL, lsym->offset - stkframesize, RBP, EAX, lsym->namestring); else asmimmed(MOVL, lhs->intval, EAX); if(rsym != NULL & rhs->tokentype != NUMBERTOK) asmldr(MOVL, rsym->offset - stkframesize, RBP, ECX, rsym->namestring); else asmimmed(MOVL, rhs->intval, ECX); asmrr(ADDL, ECX, EAX); break; case LABELOP: lhs = code->operands; asmlabel(lhs->intval); break; case IFOP: tok = code->operands; lhs = tok->operands; rhs = lhs->link; lsym = lhs->symentry; rsym = rhs->symentry; loop1 = nextlabel++; loop2 = nextlabel++; if(rhs->symtype != NULL) { if (rhs->symtype->kind == POINTERSYM) { if(lsym != NULL & lhs->tokentype != NUMBERTOK) asmldr(MOVQ, lsym->offset - stkframesize, RBP, EAX, lsym->namestring); else asmimmed(MOVQ, lhs->intval, EAX); if(rsym != NULL & rhs->tokentype != NUMBERTOK) asmldr(MOVQ, rsym->offset - stkframesize, RBP, ECX, rsym->namestring); else asmimmed(MOVQ, rhs->intval, ECX); asmrr(CMPQ, ECX, EAX); } else { if(lsym != NULL & lhs->tokentype != NUMBERTOK) asmldr(MOVL, lsym->offset - stkframesize, RBP, EAX, lsym->namestring); else asmimmed(MOVL, lhs->intval, EAX); if(rsym != NULL & rhs->tokentype != NUMBERTOK) asmldr(MOVL, rsym->offset - stkframesize, RBP, ECX, rsym->namestring); else asmimmed(MOVL, rhs->intval, ECX); asmrr(CMPL, ECX, EAX); } } else { if(lsym != NULL & lhs->tokentype != NUMBERTOK) asmldr(MOVL, lsym->offset - stkframesize, RBP, EAX, lsym->namestring); else asmimmed(MOVL, lhs->intval, EAX); if(rsym != NULL & rhs->tokentype != NUMBERTOK) asmldr(MOVL, rsym->offset - stkframesize, RBP, ECX, rsym->namestring); else asmimmed(MOVL, rhs->intval, ECX); asmrr(CMPL, ECX, EAX); } switch(tok->whichval) { case EQOP: jmpval = JE; break; case NEOP: jmpval = JNE; break; case LTOP: jmpval = JL; break; case LEOP: jmpval = JLE; break; case GEOP: jmpval = JGE; break; case GTOP: jmpval = JG; break; } asmjump(jmpval, loop1); tok = tok->link; //else part if(tok->link != NULL) genc(tok->link); asmjump(JMP, loop2); //if part asmlabel(loop1); genc(tok); asmlabel(loop2); break; case GOTOOP: lhs = code->operands; asmjump(JMP, lhs->intval); break; case FUNCALLOP: tok = code->operands; rhs = tok->link; if(rhs != NULL) { switch(rhs->tokentype) { case STRINGTOK: asmlitarg(nextlabel++, EDI); makeblit(rhs->stringval, nextlabel-1); asmcall(tok->stringval); break; case IDENTIFIERTOK: rsym = rhs->symentry; reg = getreg(WORD); asmld(MOVL, rsym->offset - stkframesize, reg, rhs->stringval); asmrr(MOVL, reg, EDI); asmcall(tok->stringval); break; case OPERATOR: rsym = rhs->symentry; reg = getreg(FLOAT); asmld(MOVL, -1000, EAX, rhs->operands->operands->stringval); asmldr(MOVSD, rhs->operands->link->intval, EAX, XMM0, "^. "); asmcall(tok->stringval); break; } } break; }; clearreg(); }
/* Example: asmst(MOVL, EAX, -code->symentry->offset, code->stringval); */ void asmsttemp( int reg ) { asmst( MOVSD, reg, -8, "temp"); }