Example #1
0
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;
}
Example #2
0
rmove()
{
	register struct node *p;
	register char *cp;
	register int r;
	int r1, flt;

	for (p=first.forw; p!=0; p = p->forw) {
	if (debug) {
		for (r=0; r<2*NREG; r++)
			if (regs[r][0])
				printf("%d: %s\n", r, regs[r]);
		printf("-\n");
	}
	flt = 0;
	switch (p->op) {

	case MOVF:
	case MOVFO:
	case MOVOF:
		flt = NREG;

	case MOV:
		dualop(p);
		if ((r = findrand(regs[RT1], flt)) >= 0) {
			if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR) {
				p->forw->back = p->back;
				p->back->forw = p->forw;
				redunm++;
				continue;
			}
		}
		repladdr(p, 0, flt);
		r = isreg(regs[RT1]);
		r1 = isreg(regs[RT2]);
		dest(regs[RT2], flt);
		if (r >= 0)
			if (r1 >= 0)
				savereg(r1+flt, regs[r+flt]);
			else
				savereg(r+flt, regs[RT2]);
		else
			if (r1 >= 0)
				savereg(r1+flt, regs[RT1]);
			else
				setcon(regs[RT1], regs[RT2]);
		source(regs[RT1]);
		setcc(regs[RT2]);
		continue;

	case ADDF:
	case SUBF:
	case DIVF:
	case MULF:
		flt = NREG;

	case ADD:
	case SUB:
	case BIC:
	case BIS:
	case MUL:
	case DIV:
	case ASH:
		dualop(p);
		repladdr(p, 0, flt);
		source(regs[RT1]);
		dest(regs[RT2], flt);
		if (p->op==DIV && (r = isreg(regs[RT2])>=0))
			regs[r+1][0] = 0;
		ccloc[0] = 0;
		continue;

	case CLRF:
	case NEGF:
		flt = NREG;

	case CLR:
	case COM:
	case INC:
	case DEC:
	case NEG:
	case ASR:
	case ASL:
	case SXT:
		singop(p);
		dest(regs[RT1], flt);
		if (p->op==CLR && flt==0)
			if ((r = isreg(regs[RT1])) >= 0)
				savereg(r, "$0");
			else
				setcon("$0", regs[RT1]);
		setcc(regs[RT1]);
		continue;

	case TSTF:
		flt = NREG;

	case TST:
		singop(p);
		repladdr(p, 0, flt);
		source(regs[RT1]);
		if (equstr(regs[RT1], ccloc)) {
			p->back->forw = p->forw;
			p->forw->back = p->back;
			p = p->back;
			nrtst++;
			nchange++;
		}
		continue;

	case CMPF:
		flt = NREG;

	case CMP:
	case BIT:
		dualop(p);
		source(regs[RT1]);
		source(regs[RT2]);
		repladdr(p, 1, flt);
		ccloc[0] = 0;
		continue;

	case CBR:
	case CFCC:
		ccloc[0] = 0;
		continue;

	case JBR:
		redunbr(p);

	default:
		clearreg();
	}
	}
}
Example #3
0
rmove()
{
	register struct node *p;
	register int r;
	register  r1, flt;

	for (p=first.forw; p!=0; p = p->forw) {
	flt = 0;
	switch (p->op) {

	case MOVF:
	case MOVFO:
	case MOVOF:
		flt = NREG;

	case MOV:
		if (p->subop==BYTE)
			goto dble;
		dualop(p);
		if ((r = findrand(regs[RT1], flt)) >= 0) {
			if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR
			   && p->forw->op!=SXT
			   && p->forw->op!=CFCC) {
				p->forw->back = p->back;
				p->back->forw = p->forw;
				redunm++;
				continue;
			}
		}
		if (equstr(regs[RT1], "$0")) {
			p->op = CLR;
			strcpy(regs[RT1], regs[RT2]);
			regs[RT2][0] = 0;
			p->code = copy(1, regs[RT1]);
			goto sngl;
		}
		repladdr(p, 0, flt);
		r = isreg(regs[RT1]);
		r1 = isreg(regs[RT2]);
		dest(regs[RT2], flt);
		if (r >= 0)
			if (r1 >= 0)
				savereg(r1+flt, regs[r+flt]);
			else
				savereg(r+flt, regs[RT2]);
		else
			if (r1 >= 0)
				savereg(r1+flt, regs[RT1]);
			else
				setcon(regs[RT1], regs[RT2]);
		source(regs[RT1]);
		setcc(regs[RT2]);
		continue;

	case ADDF:
	case SUBF:
	case DIVF:
	case MULF:
		flt = NREG;
		goto dble;

	case ADD:
	case SUB:
	case BIC:
	case BIS:
	case MUL:
	case DIV:
	case ASH:
	dble:
		dualop(p);
		if (p->op==BIC && (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777"))) {
			p->op = CLR;
			strcpy(regs[RT1], regs[RT2]);
			regs[RT2][0] = 0;
			p->code = copy(1, regs[RT1]);
			goto sngl;
		}
		if ((p->op==BIC || p->op==BIS) && equstr(regs[RT1], "$0")) {
			if (p->forw->op!=CBR) {
				p->back->forw = p->forw;
				p->forw->back = p->back;
				continue;
			}
		}
		repladdr(p, 0, flt);
		source(regs[RT1]);
		dest(regs[RT2], flt);
		if (p->op==DIV && (r = isreg(regs[RT2])>=0))
			regs[r+1][0] = 0;
		ccloc[0] = 0;
		continue;

	case CLRF:
	case NEGF:
		flt = NREG;

	case CLR:
	case COM:
	case INC:
	case DEC:
	case NEG:
	case ASR:
	case ASL:
	case SXT:
		singop(p);
	sngl:
		dest(regs[RT1], flt);
		if (p->op==CLR && flt==0)
			if ((r = isreg(regs[RT1])) >= 0)
				savereg(r, "$0");
			else
				setcon("$0", regs[RT1]);
		ccloc[0] = 0;
		continue;

	case TSTF:
		flt = NREG;

	case TST:
		singop(p);
		repladdr(p, 0, flt);
		source(regs[RT1]);
		if (equstr(regs[RT1], ccloc)) {
			p->back->forw = p->forw;
			p->forw->back = p->back;
			p = p->back;
			nrtst++;
			nchange++;
		}
		continue;

	case CMPF:
		flt = NREG;

	case CMP:
	case BIT:
		dualop(p);
		source(regs[RT1]);
		source(regs[RT2]);
		if(p->op==BIT) {
			if (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777")) {
				p->op = TST;
				strcpy(regs[RT1], regs[RT2]);
				regs[RT2][0] = 0;
				p->code = copy(1, regs[RT1]);
				nchange++;
				nsaddr++;
			} else if (equstr(regs[RT2], "$-1") || equstr(regs[RT2], "$177777")) {
				p->op = TST;
				regs[RT2][0] = 0;
				p->code = copy(1, regs[RT1]);
				nchange++;
				nsaddr++;
			}
			if (equstr(regs[RT1], "$0")) {
				p->op = TST;
				regs[RT2][0] = 0;
				p->code = copy(1, regs[RT1]);
				nchange++;
				nsaddr++;
			} else if (equstr(regs[RT2], "$0")) {
				p->op = TST;
				strcpy(regs[RT1], regs[RT2]);
				regs[RT2][0] = 0;
				p->code = copy(1, regs[RT1]);
				nchange++;
				nsaddr++;
			}
		}
		repladdr(p, 1, flt);
		ccloc[0] = 0;
		continue;

	case CBR:
		if (p->back->op==TST || p->back->op==CMP) {
			if (p->back->op==TST) {
				singop(p->back);
				savereg(RT2, "$0");
			} else
				dualop(p->back);
			r = compare(p->subop, findcon(RT1), findcon(RT2));
			if (r==0) {
				p->back->back->forw = p->forw;
				p->forw->back = p->back->back;
				decref(p->ref);
				p = p->back->back;
				nchange++;
			} else if (r>0) {
				p->op = JBR;
				p->subop = 0;
				p->back->back->forw = p;
				p->back = p->back->back;
				p = p->back;
				nchange++;
			}
		}
	case CFCC:
		ccloc[0] = 0;
		continue;

	case JBR:
		redunbr(p);

	default:
		clearreg();
	}
	}
}
Example #4
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;
	};
}
Example #5
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();
  }
Example #6
0
int mtrropt(u64t wc_addr, u64t wc_len, u32t *memlimit) {
   u32t        reg;
   int          ii, 
            sv4idx = 0;
   mtrrentry save4[16];
   memset(&save4,0,sizeof(save4));
   *memlimit = 0;

   if (is_included(wc_addr,wc_len)<0 && is_intersection(wc_addr, wc_len)<0 &&
      is_regavail(&reg))
   {
      mtrr[reg].start = wc_addr;
      mtrr[reg].len   = wc_len;
      mtrr[reg].cache = MTRRF_WC;
      mtrr[reg].on    = 1;
      return 0;
   }
   // video memory in not in 4th GB
   if (wc_addr<_3GbLL || wc_addr+wc_len>_4GbLL) return OPTERR_VIDMEM3GB;
   /* turn off previous write combine on the same memory,
      but leave this block to catch low UC border successfully */
   ii = is_include(wc_addr, wc_len);
   if (ii>=0 && mtrr[ii].cache==MTRRF_WC) mtrr[ii].cache=MTRRF_UC;
   // only WB and UC allowed in first 4Gb
   for (ii=0; ii<regs; ii++) 
      if (mtrr[ii].on && mtrr[ii].cache!=MTRRF_UC && mtrr[ii].cache!=MTRRF_WB
         && mtrr[ii].start<_4GbLL) return OPTERR_UNKCT;
   // is block intersected with someone?
   ii = is_intersection(wc_addr, wc_len);
   if (ii>=0) return OPTERR_INTERSECT;
   // remove/truncate all above 4Gb (but save it)
   for (ii=0; ii<regs; ii++)
      if (mtrr[ii].on)
         if (mtrr[ii].start<_4GbLL && mtrr[ii].start+mtrr[ii].len>_4GbLL) {
            u64t newlen = _4GbLL - mtrr[ii].start, 
                 remain = mtrr[ii].len - newlen;
            if (!is_power2(newlen)) return OPTERR_SPLIT4GB;
            mtrr[ii].len = newlen;
            // save block
            if (is_power2(remain)) {
               save4[sv4idx].start = _4GbLL;
               save4[sv4idx].len   = remain;
               save4[sv4idx].cache = mtrr[ii].cache;
               sv4idx++;
            } else
            if (is_power2(remain/3)) {
            }
         } else
         if (mtrr[ii].start>=_4GbLL || mtrr[ii].start+mtrr[ii].len>_4GbLL) {
            save4[sv4idx].start = mtrr[ii].start;
            save4[sv4idx].len   = mtrr[ii].len;
            save4[sv4idx].cache = mtrr[ii].cache;
            sv4idx++;
            clearreg(ii);
         }
   u64t  wbend = 0,
       ucstart = FFFF64;
   // searching for upper WB border
   for (ii=0; ii<regs; ii++)
      if (mtrr[ii].on)
         if (mtrr[ii].cache==MTRRF_WB)
            if (mtrr[ii].start+mtrr[ii].len > wbend)
               wbend = mtrr[ii].start+mtrr[ii].len;
   // searching for lower UC border (but ignore small blocks)
   for (ii=0; ii<regs; ii++)
      if (mtrr[ii].on)
         if (mtrr[ii].cache==MTRRF_UC) {
            int pwr = bsf64(mtrr[ii].len);
            if (pwr>=27) {
               if (ucstart>mtrr[ii].start) ucstart = mtrr[ii].start;
               clearreg(ii);
            }
         }
   // pass #2 - removing small blocks above selected border
   for (ii=0; ii<regs; ii++)
      if (mtrr[ii].on)
         if (mtrr[ii].cache==MTRRF_UC && ucstart<=mtrr[ii].start)
            clearreg(ii);
   // if no UC entries - use the end of WB as border
   if (ucstart>wbend) ucstart = wbend;
   // this can occur on small video memory size (<128Mb)
   if (wc_addr<ucstart) return OPTERR_BELOWUC;
   // build new WB list
   if (ucstart<wbend) {
      if (ucstart<_1GbLL) return OPTERR_LOWUC;

      for (ii=0; ii<regs; ii++)
         if (mtrr[ii].on)
            if (mtrr[ii].cache==MTRRF_WB) clearreg(ii);

      int regsfree = regsavail() - sv4idx - 1;
      log_it(2, "regs free: %i \n", regsfree);
      // force 3 registers (some memory above 4Gb can be lost)
      if (regsfree<3) regsfree = 3;

      // split memory to list
      u64t nextpos = 0;
      ii = 0;
      for (u64t size=_2GbLL; size>=_64MbLL; size>>=1) {
         if (ucstart>=size) {
            if (!is_regavail(&reg)) return OPTERR_NOREG;
            mtrr[reg].start = nextpos;
            nextpos += (mtrr[reg].len = size);
            mtrr[reg].cache = MTRRF_WB;
            mtrr[reg].on    = 1;
            ucstart -= size;
            // use only 3 mtrr regs
            if (++ii==regsfree) break;
         }
      }
      // save memlimit value
      *memlimit = nextpos>>20;
      /** and again removing small blocks above selected border...
         splitted blocks sum can be smaller than previously selected
         UC border and some blocks can be cleared here */
      for (ii=0; ii<regs; ii++)
         if (mtrr[ii].on)
            if (mtrr[ii].cache==MTRRF_UC && nextpos<=mtrr[ii].start)
               clearreg(ii);
   }
   // final check 
   if (is_included(wc_addr,wc_len)>=0 || is_intersection(wc_addr,wc_len)>=0 ||
      is_include(wc_addr,wc_len)>=0) return OPTERR_OPTERR;
   // add entry
   if (is_regavail(&reg)) {
      mtrr[reg].start = wc_addr;
      mtrr[reg].len   = wc_len;
      mtrr[reg].cache = MTRRF_WC;
      mtrr[reg].on    = 1;
   }
   // restore some of above 4Gb memory blocks
   if (sv4idx && regsavail()>0) {
      for (ii=0; ii<sv4idx; ii++) {
         if (!is_regavail(&reg)) break;
         mtrr[reg].start = save4[ii].start;
         mtrr[reg].len   = save4[ii].len;
         mtrr[reg].cache = save4[ii].cache;
         mtrr[reg].on    = 1;
      }
      // check lost items for included UC entries
      while (ii<sv4idx) {
         if (mtrr[ii].cache==MTRRF_UC) {
            int idx = is_included(save4[ii].start,save4[ii].len);
            if (idx<0) idx = is_intersection(save4[ii].start,save4[ii].len);
            // check it multiple times (for intersection)
            if (idx>=0) { clearreg(idx); continue; }
         }
         ii++;
      }
   }
   return 0;
}
Example #7
0
File: c21.c Project: sergev/2.11BSD
rmove()
{
	register struct node *p;
	register int r;
	register  r1, flt;

	for (p=first.forw; p!=0; p = p->forw) {
	flt = 0;
	switch (p->op) {

	case MOVF:
	case MOVFO:
	case MOVOF:
		flt = NREG;

	case MOV:
		if (p->subop==BYTE)
			goto dble;
		dualop(p);
		if ((r = findrand(regs[RT1], flt)) >= 0) {
			if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR
			   && p->forw->op!=SXT
			   && p->forw->op!=CFCC) {
				p->forw->back = p->back;
				p->back->forw = p->forw;
				redunm++;
				nchange++;
				continue;
			}
		}
		if (equstr(regs[RT1], "$0")) {
			p->op = CLR;
			strcpy(regs[RT1], regs[RT2]);
			regs[RT2][0] = 0;
			p->code = copy(1, regs[RT1]);
			nchange++;
			goto sngl;
		}
		repladdr(p, 0, flt);
		r = isreg(regs[RT1]);
		r1 = isreg(regs[RT2]);
		dest(regs[RT2], flt);
		if (r >= 0)
			if (r1 >= 0)
				savereg(r1+flt, regs[r+flt]);
			else
				savereg(r+flt, regs[RT2]);
		else
			if (r1 >= 0)
				savereg(r1+flt, regs[RT1]);
			else
				setcon(regs[RT1], regs[RT2]);
		source(regs[RT1]);
		setcc(regs[RT2]);
		continue;

	case ADDF:
	case SUBF:
	case DIVF:
	case MULF:
		flt = NREG;
		goto dble;

	case ADD:
	case SUB:
	case BIC:
	case BIS:
	case MUL:
	case DIV:
	case ASH:
	dble:
		dualop(p);
		if (p->op==BIC && (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777"))) {
			p->op = CLR;
			strcpy(regs[RT1], regs[RT2]);
			regs[RT2][0] = 0;
			p->code = copy(1, regs[RT1]);
			nchange++;
			goto sngl;
		}
		if ((p->op==BIC || p->op==BIS) && equstr(regs[RT1], "$0")) {
			if (p->forw->op!=CBR) {
				p->back->forw = p->forw;
				p->forw->back = p->back;
				nchange++;
				continue;
			}
		}
/*
 * the next block of code looks for the sequences (which extract the
 * high byte of a word or the low byte respectively):
 *	ash $-10,r
 *	bic $-400,r
 * or 
 *	mov natural,r
 *	bic $-400,r
 * and transforms them into:
 *	clrb r
 *	swab r
 * or
 *	clr r
 *	bisb natural,r
 * These constructs occur often enough in the kernel (dealing with major/minor 
 * device numbers, etc) it's worth a little extra work at compile time.
*/
		if (p->op == BIC && (equstr(regs[RT1],"$-400") || 
			 equstr(regs[RT1],"$-177400"))) {
			if (p->back->op == ASH) {
				r = isreg(regs[RT2]);
				dualop(p->back);
				if ((equstr(regs[RT1], "$-10") || 
				     equstr(regs[RT1], "$177770")) && 
				    r == isreg(regs[RT2])) {
					strcpy(regs[RT1], regs[RT2]);
					regs[RT2][0] = 0;
					p->back->op = CLR;
					p->back->subop = BYTE;
					p->back->code = copy(1, regs[RT1]);
					p->op = SWAB;
					p->code = copy(1, regs[RT1]);
					nchange++;
					goto sngl;
				}
			}
			else if (p->back->op == MOV && p->forw->op != CBR) {
				char temp[50];

				r = isreg(regs[RT2]);
				if (r < 0 && !xnatural(regs[RT2]))
					goto out;
				strcpy(temp, regs[RT2]);
				dualop(p->back);
				if (isreg(regs[RT2]) == r && natural(regs[RT1])) {
			 	    if (r < 0 && (!xnatural(regs[RT2]) || !equstr(temp, regs[RT2])))
					goto out;
/*
 * XXX - the sequence "movb rN,rN; bic $-400,rN" can not be transformed
 * because the 'clr' would lose all information about 'rN'.  The best that can 
 * be done is to remove the 'movb' instruction and leave the 'bic'.
*/
				    if (isreg(regs[RT1]) == r && r >= 0) {
					    p = p->back;
					    p->forw->back = p->back;
					    p->back->forw = p->forw;
					    nchange++;
					    continue;
				    }
				    dest(regs[RT1], flt);
				    p->back->op = CLR;
				    p->back->subop = 0;
				    p->back->code = copy(1, regs[RT2]);
				    p->op = BIS;
				    p->subop = BYTE;
				    strcat(regs[RT1], ",");
				    p->code = copy(2, regs[RT1], regs[RT2]);
				    nchange++;
				}
			}
out:		dualop(p);	/* restore banged up parsed operands */
		}
		repladdr(p, 0, flt);
		source(regs[RT1]);
		dest(regs[RT2], flt);
		if (p->op==DIV && (r = isreg(regs[RT2]))>=0)
			regs[r|1][0] = 0;
		switch	(p->op)
			{
			case	ADD:
			case	SUB:
			case	BIC:
			case	BIS:
			case	ASH:
				setcc(regs[RT2]);
				break;
			default:
				ccloc[0] = 0;
			}
		continue;

	case SXT:
		singop(p);
		if (p->forw->op == CLR && p->forw->subop != BYTE &&
			xnatural(regs[RT1]) && !strcmp(p->code, p->forw->code)){
			p->forw->back = p->back;
			p->back->forw = p->forw;
			nchange++;
			continue;
		}
		goto sngl;
	case CLRF:
	case NEGF:
		flt = NREG;

	case CLR:
	case COM:
	case INC:
	case DEC:
	case NEG:
	case ASR:
	case ASL:
	case SWAB:
		singop(p);
	sngl:
		dest(regs[RT1], flt);
		if (p->op==CLR && flt==0)
			{
			if ((r = isreg(regs[RT1])) >= 0)
				savereg(r, "$0");
			else
				setcon("$0", regs[RT1]);
			ccloc[0] = 0;
			}
		else
			setcc(regs[RT1]);
		continue;

	case TSTF:
		flt = NREG;

	case TST:
		singop(p);
		repladdr(p, 0, flt);
		source(regs[RT1]);
		if (p->back->op == TST && !flt && not_sp(regs[RT1])) {
			char rt1[MAXCPS + 2];
			strcpy(rt1, regs[RT1]);
			singop(p->back);
			if (!strcmp("(sp)+", regs[RT1])) {
				p->back->subop = p->subop;
				p->back->forw = p->forw;
				p->forw->back = p->back;
				p = p->back;
				p->op = MOV;
				p->code = copy(2, rt1, ",(sp)+");
				nrtst++;
				nchange++;
				continue;
			}
		singop(p);
		}
		if (p->back->op == MOV && p->back->subop == BYTE) {
			dualop(p->back);
			setcc(regs[RT2]);
			singop(p);
		}
		if (equstr(regs[RT1], ccloc) && p->subop == p->back->subop) {
			p->back->forw = p->forw;
			p->forw->back = p->back;
			p = p->back;
			nrtst++;
			nchange++;
		}
		else
			setcc(regs[RT1]); /* XXX - double TST in a row */
		continue;

	case CMPF:
		flt = NREG;

	case CMP:
	case BIT:
		dualop(p);
		source(regs[RT1]);
		source(regs[RT2]);
		if(p->op==BIT) {
			if (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777")) {
				p->op = TST;
				strcpy(regs[RT1], regs[RT2]);
				regs[RT2][0] = 0;
				p->code = copy(1, regs[RT1]);
				nchange++;
				nsaddr++;
			} else if (equstr(regs[RT2], "$-1") || equstr(regs[RT2], "$177777")) {
				p->op = TST;
				regs[RT2][0] = 0;
				p->code = copy(1, regs[RT1]);
				nchange++;
				nsaddr++;
			}
			if (equstr(regs[RT1], "$0")) {
				p->op = TST;
				regs[RT2][0] = 0;
				p->code = copy(1, regs[RT1]);
				nchange++;
				nsaddr++;
			} else if (equstr(regs[RT2], "$0")) {
				p->op = TST;
				strcpy(regs[RT1], regs[RT2]);
				regs[RT2][0] = 0;
				p->code = copy(1, regs[RT1]);
				nchange++;
				nsaddr++;
			}
		}
		repladdr(p, 1, flt);
		ccloc[0] = 0;
		continue;

	case CBR:
		r = -1;
		if (p->back->op==TST || p->back->op==CMP) {
			if (p->back->op==TST) {
				singop(p->back);
				savereg(RT2, "$0");
			} else
				dualop(p->back);
			if (equstr(regs[RT1], regs[RT2])
			 && natural(regs[RT1]) && natural(regs[RT2]))
				r = compare(p->subop, "$1", "$1");
			else
				r = compare(p->subop, findcon(RT1), findcon(RT2));
			if (r==0) {
				if (p->forw->op==CBR
				  || p->forw->op==SXT
				  || p->forw->op==CFCC) {
					p->back->forw = p->forw;
					p->forw->back = p->back;
				} else {
					p->back->back->forw = p->forw;
					p->forw->back = p->back->back;
				}
				decref(p->ref);
				p = p->back->back;
				nchange++;
			} else if (r>0) {
				p->op = JBR;
				p->subop = 0;
				p->back->back->forw = p;
				p->back = p->back->back;
				p = p->back;
				nchange++;
			}
/*
 * If the instruction prior to the conditional branch was a 'tst' then
 * save the condition code status.  The C construct:
 * 		if (x) 
 *		   if (x > 0)
 * generates "tst _x; jeq ...; tst _x; jmi ...;jeq ...".  The code below removes
 * the second "tst _x", leaving "tst _x; jeq ...;jmi ...; jeq ...".
*/
			if (p->back->op == TST) {
				singop(p->back);
				setcc(regs[RT1]);
				break;
			}
		}
/*
 * If the previous instruction was also a conditional branch then
 * attempt to merge the two into a single branch.
*/
		if (p->back->op == CBR)
			fixupbr(p);
	case CFCC:
		ccloc[0] = 0;
		continue;

/*
 * Unrecognized (unparsed) instructions, assignments (~foo=r2), and
 * data arrive here.  In order to prevent throwing away information
 * about register contents just because a local assignment is done
 * we check for the first character being a tilde.
*/
	case 0:
		if (p->code[0] != '~')
			clearreg();
		continue;

	case JBR:
		redunbr(p);

	default:
		clearreg();
	}
	}
}