示例#1
0
/* 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;
	 };
  }
示例#2
0
文件: parsc.c 项目: hbarve1/Compilers
TOKEN cons(TOKEN item, TOKEN list)           /* add item to front of list */
  { item->link = list;
    if (DEBUG & DB_CONS)
       { printf("cons\n");
         dbugprinttok(item);
         dbugprinttok(list);
       };
    return item;
  }
示例#3
0
文件: parsc.c 项目: hbarve1/Compilers
TOKEN makeprogn(TOKEN tok, TOKEN statements)
  {  tok->tokentype = OPERATOR;
     tok->whichval = PROGNOP;
     tok->operands = statements;
     if (DEBUG & DB_MAKEPROGN)
       { printf("makeprogn\n");
         dbugprinttok(tok);
         dbugprinttok(statements);
       };
     return tok;
   }
示例#4
0
文件: parsc.c 项目: hbarve1/Compilers
TOKEN binop(TOKEN op, TOKEN lhs, TOKEN rhs)       /* reduce binary operator */
            /* operator, left-hand side, right-hand side */
  { op->operands = lhs;         /* link operands to operator       */
    lhs->link = rhs;            /* link second operand to first    */
    rhs->link = NULL;           /* terminate operand list          */
    if (DEBUG & DB_BINOP)
       { printf("binop\n");
         dbugprinttok(op);      /*       op         =  (op lhs rhs)      */
         dbugprinttok(lhs);     /*      /                                */
         dbugprinttok(rhs);     /*    lhs --- rhs                        */
       };
    return op;
  }
示例#5
0
文件: parsc.c 项目: hbarve1/Compilers
TOKEN makeif(TOKEN tok, TOKEN exp, TOKEN thenpart, TOKEN elsepart)
  {  tok->tokentype = OPERATOR;  /* Make it look like an operator   */
     tok->whichval = IFOP;
     if (elsepart != NULL) elsepart->link = NULL;
     thenpart->link = elsepart;
     exp->link = thenpart;
     tok->operands = exp;
     if (DEBUG & DB_MAKEIF)
        { printf("makeif\n");
          dbugprinttok(tok);
          dbugprinttok(exp);
          dbugprinttok(thenpart);
          dbugprinttok(elsepart);
        };
     return tok;
   }
示例#6
0
void printexpr(TOKEN tok, int col)     /* print an expression in prefix form */
  { TOKEN opnds; int nextcol, start, i;
    if (PRINTEXPRDEBUG != 0)
      { printf ("printexpr: col %d\n", col);
        dbugprinttok(tok);
      };
    if (tok->tokentype == OPERATOR)
      { printf ("(%s", opprint[tok->whichval]);
        nextcol = col + 2 + opsize[tok->whichval];
        opnds = tok->operands;
	start = 0;
	while (opnds != NULL)
	  { if (start == 0) 
	       printf(" ");
	       else { printf("\n");
		      for (i = 0; i < nextcol; i++) printf(" ");
		    }
	    printexpr(opnds, nextcol);
	    if ( opnds->tokentype == IDENTIFIERTOK && nextcol < 60 )
	       nextcol = nextcol + 1 + strlength(opnds->stringval);
	       else start = 1;
	    opnds = opnds->link;
	  }
        printf (")");
      }
      else printtok(tok);
  }
示例#7
0
/* Generate code for arithmetic expression, return a register number */
int genarith(TOKEN code)
  {   int num, reg;
     if (DEBUGGEN)
       { printf("genarith\n");
	 dbugprinttok(code);
       };
      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:
    /*     ***** fix this *****   */
		 break;
	       }
	   break;
       case IDENTIFIERTOK:
    /*     ***** fix this *****   */
	   break;
       case OPERATOR:
    /*     ***** fix this *****   */
	   break;
       };
     return reg;
    }
示例#8
0
void dbugprintexpr(TOKEN tok) /* print an expression in 'nice' debugging form */
  { TOKEN opnds;
    dbugprinttok(tok);
    if (tok->tokentype == OPERATOR)
      { opnds = tok->operands;
	while (opnds != NULL)
	      { dbugprintexpr(opnds);
		opnds = opnds->link;
	      }
      }
  }
示例#9
0
/* Generate code for arithmetic expression, return a register number */
int genarith(TOKEN code) {

    if (DEBUGGEN) {
        printf("In genarith()\n");
        dbugprinttok(code);
    }

    int num, reg_num, lhs_reg, rhs_reg;

    if (code->tokentype == NUMBERTOK) {
        if (code->datatype == INTEGER) {
            num = code->intval;
            reg_num = getreg(INTEGER);
            if (num >= MINIMMEDIATE && num <= MAXIMMEDIATE) {
                asmimmed(MOVL, num, reg_num);
            }
            else {

                /* Generate literal for the value of the constant, then
                   load the literal into a register. */

            }

        }
        else {
            /* Generate literal for the value of the constant, then
               load the literal into a register. */

            num = code->intval;
            reg_num = getreg(REAL);
        }
    }
    else if (code->tokentype == IDENTIFIERTOK) {

    }
    else if (code->tokentype == OPERATOR) {

        reg_num = lhs_reg;
    }

    return reg_num;
}
示例#10
0
/* 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;
}
示例#11
0
/* 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;
	};
}
示例#12
0
void dbugplist(TOKEN tok)           /* print a list of tokens for debugging */
  { while (tok != NULL)
      { dbugprinttok(tok);
        tok = tok->link;
      };
  }
示例#13
0
/* 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;
  }
示例#14
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();
  }