/* 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; }; }
int genfun(TOKEN code) { int reg; //Load args //printf("here\n"); if((code->operands)->link != NULL) { reg = genarith((code->operands)->link); if(((code->operands)->link)->tokentype == STRINGTOK) { asmlitarg(reg, EDI); } else if(((code->operands)->link)->tokentype == NUMBERTOK && ((code->operands)->link)->datatype == INTEGER) { asmrr(MOVL, reg, EDI); reg_map[reg] = 0; reg = EDI; } else if(((code->operands)->link)->tokentype == IDENTIFIERTOK) { asmrr(MOVL, reg, EDI); reg_map[reg] = 0; reg = EDI; } clearreg(); reg_map[reg] = 1; } savereg(); asmcall(code->operands->stringval); restorereg(); if(code->datatype == REAL) return FBASE; else if(code->datatype == INTEGER) return RAX; }
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 arithmetic expression, return a register number */ int genarith(TOKEN code) { int num, reg; float fnum; TOKEN lhs, rhs; int reg1, reg2, freg; int offs; if (DEBUGGEN) { printf("genarith\n"); dbugprinttok(code); }; //printf("tokentype: %i\n", code->tokentype); switch ( code->tokentype ) { case NUMBERTOK: switch (code->datatype) { case INTEGER: num = code->intval; reg = getreg(WORD); if ( num >= MINIMMEDIATE && num <= MAXIMMEDIATE ) asmimmed(MOVL, num, reg); break; case REAL: fnum = code->realval; reg = getreg(FLOAT); makeflit(fnum, nextlabel); asmldflit(MOVSD, nextlabel, reg); nextlabel++; break; case POINTER: num = 0; reg = getreg(WORD); asmimmed(MOVQ, num, reg); break; } break; case IDENTIFIERTOK: offs = code->symentry->offset - stkframesize; /* net offset of the var */ switch(code->datatype) { case INTEGER: reg = getreg(WORD); //printf("kind: %i\n", code->symtype->datatype->kind); if(code->symtype == NULL || code->symtype->kind == BASICTYPE) asmld(MOVL, offs, reg, code->stringval); else asmld(MOVQ, offs, reg, code->stringval); break; case REAL: reg = getreg(FLOAT); asmld(MOVSD, offs, reg, code->stringval); break; } break; case OPERATOR: if(code->whichval != FUNCALLOP && code->whichval != AREFOP) { lhs = code->operands; rhs = lhs->link; if(code->datatype == REAL) { reg1 = genarith( lhs ); if(rhs != NULL) { if(rhs->tokentype == OPERATOR && rhs->whichval == FUNCALLOP) { asmsttemp(reg1); reg_map[reg1] = 0; reg2 = genarith( rhs ); reg1 = getreg(FLOAT); asmldtemp(reg1); } else { reg2 = genarith( rhs ); } } } else { reg1 = genarith( lhs ); if(rhs != NULL) reg2 = genarith( rhs ); } } switch(code->whichval) { case PLUSOP: if(code->datatype == INTEGER) asmrr(ADDL, reg2, reg1); else asmrr(ADDSD, reg2, reg1); reg = reg1; break; case MINUSOP: if(rhs != NULL) { if(code->datatype == INTEGER) asmrr(SUBL, reg2, reg1); else asmrr(SUBSD, reg2, reg1); } else { reg2 = getreg(FLOAT); asmfneg(reg1, reg2); reg_map[reg2] = 0; } reg = reg1; break; case TIMESOP: if(code->datatype == INTEGER) asmrr(IMULL, reg2, reg1); else asmrr(MULSD, reg2, reg1); reg = reg1; break; case DIVIDEOP: if(code->datatype == INTEGER) asmrr(DIVL, reg2, reg1); else asmrr(DIVSD, reg2, reg1); reg = reg1; break; case EQOP: case NEOP: case LTOP: case LEOP: case GEOP: case GTOP: asmrr(CMPL, reg2, reg1); reg = reg1; break; case FLOATOP: freg = getreg(FLOAT); asmfloat(reg1, freg); reg_map[reg1] = 0; reg = freg; break; case FIXOP: reg2 = getreg(WORD); asmfix(reg1, reg2); reg_map[freg] = 0; reg = reg2; break; case FUNCALLOP: reg = genfun(code); break; case AREFOP: reg = genaref(code, FBASE); break; } break; case STRINGTOK: makeblit(code->stringval, nextlabel); return nextlabel++; break; }; return reg; }
/* 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 arithmetic expression, return a register number */ int genarith(TOKEN code) { int num1, num2, reg1, reg2, offs; TOKEN tok, lhs, rhs; SYMBOL sym, lsym, rsym; if (DEBUGGEN) { printf("genarith\n"); dbugprinttok(code); }; // This switch determines how to handle the token based on its type switch ( code->tokentype ) { case NUMBERTOK: switch (code->datatype) { case INTEGER: num1 = code->intval; reg1 = getreg(WORD); if (code->symtype != NULL) { if(code->symtype->kind == POINTERSYM) asmimmed(MOVQ, num1, reg1); } else if ( num1 >= MINIMMEDIATE && num1 <= MAXIMMEDIATE ) asmimmed(MOVL, num1, reg1); break; case REAL: reg1 = getreg(FLOAT); makeflit(code->realval, nextlabel++); asmldflit(MOVSD, nextlabel-1, reg1); break; } break; case IDENTIFIERTOK: reg1 = getreg(WORD); sym = code->symentry; offs = sym->offset - stkframesize; asmld(MOVQ, offs, reg1, code->stringval); break; case OPERATOR: switch(code->whichval) { case PLUSOP: lhs = code->operands; rhs = lhs->link; lsym = lhs->symentry; rsym = rhs->symentry; if(lsym != NULL & lhs->tokentype != NUMBERTOK) { switch(lsym->basicdt) { case INTEGER: reg1 = getreg(WORD); break; case REAL: reg1 = getreg(FLOAT); break; } asmldr(MOVL, lsym->offset - stkframesize, RBP, reg1, lsym->namestring); } else { if(lhs->tokentype == OPERATOR) reg1 = genarith(lhs); else switch(lhs->datatype) { case INTEGER: reg1 = getreg(WORD); asmimmed(MOVL, lhs->intval, reg1); break; case REAL: reg1 = getreg(FLOAT); makeflit(lhs->realval, nextlabel++); asmldflit(MOVSD, nextlabel-1, reg1); break; } } if(rsym != NULL & rhs->tokentype != NUMBERTOK) { switch(rsym->basicdt) { case INTEGER: reg2 = getreg(WORD); break; case REAL: reg2 = getreg(FLOAT); break; } asmldr(MOVL, rsym->offset - stkframesize, RBP, reg2, rsym->namestring); } else { if(rhs->tokentype == OPERATOR) reg2 = genarith(rhs); else switch(rhs->datatype) { case INTEGER: reg2 = getreg(WORD); asmimmed(MOVL, rhs->intval, reg2); break; case REAL: reg2 = getreg(FLOAT); makeflit(rhs->realval, nextlabel++); asmldflit(MOVSD, nextlabel-1, reg2); break; } } if(reg1 < 8 & reg2 < 8) asmrr(ADDL, reg2, reg1); else asmrr(ADDSD, reg2, reg1); unused(reg2); break; case MINUSOP: lhs = code->operands; lsym = lhs->symentry; rhs = lhs->link; if(rhs == NULL) //if this is just a negation { if(lsym != NULL & lhs->tokentype != NUMBERTOK) { switch(lsym->basicdt) { case INTEGER: reg1 = getreg(WORD); asmldr(MOVL, lsym->offset - stkframesize, RBP, reg1, lsym->namestring); break; case REAL: reg1 = getreg(FLOAT); reg2 = getreg(FLOAT); asmldr(MOVSD, lsym->offset - stkframesize, RBP, reg1, lsym->namestring); asmfneg(reg1, reg2); unused(reg2); break; } } else { if(lhs->tokentype == OPERATOR) reg1 = genarith(lhs); else switch(lhs->datatype) { case INTEGER: reg1 = getreg(WORD); asmimmed(MOVL, lhs->intval, reg1); break; case REAL: reg1 = getreg(FLOAT); reg2 = getreg(FLOAT); asmldflit(MOVSD, nextlabel++, reg1); asmfneg(reg1, reg2); unused(reg2); break; } } return reg1; } rsym = rhs->symentry; if(lsym != NULL & lhs->tokentype != NUMBERTOK) { switch(lsym->basicdt) { case INTEGER: reg1 = getreg(WORD); asmldr(MOVL, lsym->offset - stkframesize, RBP, reg1, lsym->namestring); break; case REAL: reg1 = getreg(FLOAT); asmldr(MOVSD, lsym->offset - stkframesize, RBP, reg1, lsym->namestring); break; } } else { if(lhs->tokentype == OPERATOR) reg1 = genarith(lhs); else switch(lhs->datatype) { case INTEGER: reg1 = getreg(WORD); asmimmed(MOVL, lhs->intval, reg1); break; case REAL: reg1 = getreg(FLOAT); makeflit(lhs->realval, nextlabel++); asmldflit(MOVSD, nextlabel-1, reg1); break; } } if(rsym != NULL & rhs->tokentype != NUMBERTOK) { switch(rsym->basicdt) { case INTEGER: reg2 = getreg(WORD); asmldr(MOVL, rsym->offset - stkframesize, RBP, reg2, rsym->namestring); break; case REAL: reg2 = getreg(FLOAT); asmldr(MOVSD, rsym->offset - stkframesize, RBP, reg2, rsym->namestring); break; } } else { if(rhs->tokentype == OPERATOR) reg2 = genarith(rhs); else switch(rhs->datatype) { case INTEGER: reg2 = getreg(WORD); asmimmed(MOVL, rhs->intval, reg2); break; case REAL: reg2 = getreg(FLOAT); makeflit(rhs->realval, nextlabel++); asmldflit(MOVSD, nextlabel-1, reg2); break; } } if(reg1 < 8 & reg2 < 8) asmrr(SUBL, reg2, reg1); else asmrr(SUBSD, reg2, reg1); unused(reg2); break; case TIMESOP: lhs = code->operands; rhs = lhs->link; lsym = lhs->symentry; rsym = rhs->symentry; if(lsym != NULL & lhs->tokentype != NUMBERTOK) { switch(lsym->basicdt) { case INTEGER: reg1 = getreg(WORD); asmldr(MOVL, lsym->offset - stkframesize, RBP, reg1, lsym->namestring); break; case REAL: reg1 = getreg(FLOAT); asmldr(MOVSD, lsym->offset - stkframesize, RBP, reg1, lsym->namestring); break; } } else { if(lhs->tokentype == OPERATOR) { reg1 = genarith(lhs); if(lhs->whichval == FUNCALLOP & rhs->whichval == FUNCALLOP) { asmsttemp(reg1); unused(reg1); } } else switch(lhs->datatype) { case INTEGER: reg1 = getreg(WORD); asmimmed(MOVL, lhs->intval, reg1); break; case REAL: reg1 = getreg(FLOAT); makeflit(lhs->realval, nextlabel++); asmldflit(MOVSD, nextlabel-1, reg1); break; } } if(rsym != NULL & rhs->tokentype != NUMBERTOK) { switch(rsym->basicdt) { case INTEGER: reg2 = getreg(WORD); asmldr(MOVL, rsym->offset - stkframesize, RBP, reg2, rsym->namestring); break; case REAL: reg2 = getreg(FLOAT); asmldr(MOVSD, rsym->offset - stkframesize, RBP, reg2, rsym->namestring); break; } } else { if(rhs->tokentype == OPERATOR) { reg2 = genarith(rhs); if(lhs->whichval == FUNCALLOP & rhs->whichval == FUNCALLOP) { switch(lhs->datatype) { case INTEGER: reg1 = getreg(WORD); break; case REAL: reg1 = getreg(FLOAT); break; } asmldtemp(reg1); } } else switch(rhs->datatype) { case INTEGER: reg2 = getreg(WORD); asmimmed(MOVL, rhs->intval, reg2); break; case REAL: reg2 = getreg(FLOAT); makeflit(rhs->realval, nextlabel++); asmldflit(MOVSD, nextlabel-1, reg2); break; } } if(reg1 < 8 & reg2 < 8) asmrr(IMULL, reg2, reg1); else asmrr(MULSD, reg2, reg1); unused(reg2); break; case FLOATOP: lhs = code->operands; lsym = lhs->symentry; reg1 = getreg(FLOAT); reg2 = getreg(WORD); asmldr(MOVL, lsym->offset - stkframesize, RBP, reg2, lsym->namestring); asmfloat(reg2, reg1); unused(reg2); break; case FUNCALLOP: tok = code->operands; if(tok->link != NULL) { switch(tok->link->tokentype) { case STRINGTOK: asmlitarg(nextlabel++, EDI); makeblit(tok->link->stringval, nextlabel-1); asmcall(tok->stringval); break; case OPERATOR: reg1 = genarith(tok->link); break; case NUMBERTOK: switch(tok->link->datatype) { case INTEGER: reg1 = getreg(WORD); asmimmed(MOVL,tok->link->intval,reg1); asmrr(MOVL, reg1, EDI); break; case REAL: reg1 = getreg(FLOAT); asmimmed(MOVSD,tok->link->realval,reg1); asmrr(MOVSD, reg1, EDI); break; } } } asmcall(tok->stringval); break; case FIXOP: reg1 = getreg(WORD); reg2 = genarith(code->operands); asmfix(reg2,reg1); break; case POINTEROP: lhs = code->operands; if(lhs->tokentype == OPERATOR & lhs->whichval == AREFOP) { reg1 = genarith(lhs); } else { reg1 = getreg(WORD); lsym = code->operands->symentry; asmld(MOVQ, lsym->offset - stkframesize, reg1, code->operands->stringval); } break; case AREFOP: lhs = code->operands; rhs = lhs->link; if(lhs->tokentype == OPERATOR & lhs->whichval == POINTEROP) { reg2 = genarith(lhs->operands); if(lhs->symtype != NULL) { if(lhs->symtype->basicdt == REAL) { reg1 = getreg(FLOAT); asmldr(MOVSD, rhs->intval, reg2, reg1, "^. "); unused(reg2); break; } } reg1 = getreg(WORD); asmldr(MOVQ, rhs->intval, reg2, reg1, "^. "); } unused(reg2); break; } break; }; return reg1; }
/* 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(); }