예제 #1
0
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, "^. ");
	}
}
예제 #2
0
/* 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();
  }