int genaref(TOKEN code, int storereg) { int reg; if(code->operands->tokentype == OPERATOR) { if(code->link != NULL) { if(code->operands->operands->whichval == AREFOP) { asmstr(MOVL, storereg, 0, ECX, "^. "); return 0; } int ofs = ((code->operands))->operands->symentry->offset - stkframesize; int ofs2 = ((code->operands)->link)->intval; asmld(MOVQ, ofs, ECX, ((code->operands)->operands)->stringval); if(code->link != NULL && code->link->tokentype != IDENTIFIERTOK && code->link->datatype != POINTER) asmstr(MOVL, storereg, ofs2, ECX, "^. "); else asmstr(MOVQ, storereg, ofs2, ECX, "^. "); } else { int ofs = ((code->operands))->operands->symentry->offset - stkframesize; int ofs2 = ((code->operands)->link)->intval; asmld(MOVQ, ofs, ECX, ((code->operands)->operands)->stringval); asmstr(MOVL, storereg, ofs2, ECX, "^. "); return ECX; } } else if(code->operands->tokentype == IDENTIFIERTOK) { int arofs = code->operands->symentry->offset - stkframesize; reg = genarith(code->operands->link); asmop(CLTQ); asmstrr(MOVSD, storereg, arofs, ECX, "^. "); } }
/* 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(); }