⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccjskp.c

📁 KCC , a good c compiler, write by Ken Harrenstien
💻 C
📖 第 1 页 / 共 3 页
字号:
    }

    p = before(previous);
    if (p != NULL && oneinstr(previous) && p->Pop == P_CAI+POF_ISSKIP+POS_SKPE &&
	p->Ptype == PTA_RCONST && (q = before(p)) != NULL && q->Pop == P_JRST &&
	q->Pptr == lab && (b = before(q)) != NULL && !prevskips (b))
    switch(b->Pop) {
	/*
	** fold:  CAIN R,x
	**         JRST lab
	**        CAIE R,x+1
	**         instr
	**     lab:
	**
	** into:  CAIL R,x
	**         CAILE R,x+1
	**          instr
	**     lab:
	*/

    case P_AOS+POF_ISSKIP+POS_SKPN:
	if (p->Pvalue == 1) {
	    b->Pop = P_AOS+POF_ISSKIP+POS_SKPL;
	    dropjump(q);
	    p->Pop = P_CAI+POF_ISSKIP+POS_SKPLE;
	    setskip(p);
	}
	break;

    case P_SKIP+POF_ISSKIP+POS_SKPN:
	if (p->Pvalue == 1) {
	    b->Pop = P_SKIP+POF_ISSKIP+POS_SKPL;
	    dropjump(q);
	    p->Pop = P_CAI+POF_ISSKIP+POS_SKPLE;
	    setskip(p);
	}
	break;

    case P_SOS+POF_ISSKIP+POS_SKPN:
	if (p->Pvalue == 1) {
	    b->Pop = P_SOS+POF_ISSKIP+POS_SKPL;
	    dropjump(q);
	    p->Pop = P_CAI+POF_ISSKIP+POS_SKPLE;
	    setskip(p);
	}
	break;

    case P_CAI+POF_ISSKIP+POS_SKPN:
	if (b->Ptype != PTA_RCONST) break;
	if (b->Pvalue + 1 == p->Pvalue) {
	    b->Pop = P_CAI+POF_ISSKIP+POS_SKPL;
	    dropjump(q);
	    p->Pop = P_CAI+POF_ISSKIP+POS_SKPLE;
	    setskip(p);
	} else if (b->Pvalue == p->Pvalue + 1) {
	    b->Pop = P_CAI+POF_ISSKIP+POS_SKPL;
	    b->Pvalue--;		/* note foldskip unsafe here! */
	    dropjump(q);		/* might be in a recursive casejump */
	    setskip(p);
	    p->Pop = P_CAI+POF_ISSKIP+POS_SKPLE;
	    p->Pvalue++;
	}
    }					/* end switch(b->Pop) */

    foldjump(previous, lab);		/* common optimizations with JRST */
    if (!oneinstr (previous) || (p = before (previous)) == NULL) return;

    /* fold  P_JUMPx R,lab / instr / lab::  into  P_CAIx R,0 / instr */
    if (p->Pptr == lab) {
	jumptoskip(p);			/* make into skip */
	if (isskip(p->Pop)) setskip(previous); /* set instr skipped */
	crossjump(previous, lab);	/* now retry pulling JUMPx across */
	p = before(previous);		/* fix up again */
    }

    /*
    ** Remaining optimizations work for jumps over two instructions.
    ** If we don't have that, give up.  If (q->Pptr == lab) then q is
    ** a jump instruction.
    */

    if ((q = before (p)) == NULL || (q->Ptype & PTF_ADRMODE) != PTA_MINDEXED 
#if SYS_CSI		/*  Reg linkage */
        || Register_Preserve(p->Preg)   /* avoid faulty optimizations */
#endif
	|| q->Pptr != lab) return;	/* make sure some jump to lab */

    /*
    ** fold:  P_JUMPx R,$n
    **	      P_MOVE S,R
    **	      op
    **	    $n::
    **
    ** into:  P_SKIPx S,R
    **	       op
    */

    if (p->Pop == P_MOVE && p->Ptype == PTA_REGIS && q->Preg == p->Pr2 &&
	!prevskips (q)) switch (q->Pop & POF_OPCODE) {
    case P_JUMP:
	p->Pop = q->Pop ^ (P_JUMP ^ P_SKIP ^ POF_ISSKIP);
	dropjump (q);
	setskip(previous);
	optlab(lab);			/* try again */
	return;				/* tail recursively */

    case P_AOJ:
	p->Pop = q->Pop ^ (P_AOJ ^ P_AOS ^ POF_ISSKIP);
	dropjump (q);
	setskip(previous);
	optlab(lab);			/* try again */
	return;				/* tail recursively */

    case P_SOJ:
	p->Pop = q->Pop ^ (P_SOJ ^ P_SOS ^ POF_ISSKIP);
	dropjump (q);
	setskip(previous);
	optlab(lab);			/* try again */
	return;				/* tail recursively */
    }

    /* A couple of these deal with skipping over P_MOVEMs */
    if (previous->Pop == P_MOVEM && p->Pop == P_MOVE && p->Preg == previous->Preg)
    {
	if (p->Ptype == PTV_IMMED && p->Pvalue == 1 && q->Pop== P_SOJ+POS_SKPN
#if SYS_CSI		/*  Reg linkage */
	    && (Register_Nopreserve (p->Preg)) /*avoid faulty optimizations */
#endif

	    && !prevskips (q) && changereg (p->Preg, q->Preg, before (q))) {

	    /*
	    ** fold:  P_SOJN R,$x
	    **	      P_MOVEI S,1
	    **	      P_MOVEM S,y
	    **	    $x::
	    **
	    ** into:  P_CAIN R,1
	    **	      P_MOVEM R,y
	    */

	    dropjump (q);		/* flush P_SOJN */
	    p->Pop = P_CAI+POF_ISSKIP+POS_SKPN;	/* make skip comparison */
	    p->Ptype = PTA_RCONST;		/* immediate built in to P_CAI */
	    p->Pvalue = 1;		/* against one */
	    setskip(previous);		/* movem is now skipped over */
	    optlab(lab);		/* try again */
	    return;			/* tail recursively */
	}

	/*
	** fold:  P_MOVEM R,x
	**	  P_JUMPy S,lab
	**	  P_MOVE T,w
	**	  P_MOVEM T,x
	**
	** into:  P_CAIy S,0
	**	  P_MOVE R,y
	**	  P_MOVEM R,x
	*/

	/*
	 * Starting at q (third instruction before label), scan backwards
	 * for a MOVEM.  If we find one BEFORE (not at) q, check it for
	 * two criteria.
	 */

	for (b = q; b != NULL; b = before (b))
	    if (b->Pop == P_MOVEM) {		/* Find MOVEM if any */
		if (prevskips(b)) b = NULL;	/*Forget it if it's skipped */
#if SYS_CSI		/*  Reg linkage */
		if (Register_Preserve (b->Preg))
		    b = NULL;	 /* avoid faulty opts */
#endif
		break;
	    }

	/*
	 * Starting after the MOVEM we just found, scan forward checking
	 * for criteria to proceed.  Some opcodes are OK regardless, some
	 * must be checked to ensure that they don't touch our register,
	 * and all others are right out.
	 */

	for (bb = after(b); b != NULL && bb != NULL && bb != p; bb = after(bb))
	    switch (bb->Pop & POF_OPCODE) {
		case P_MOVE: case P_ADD: case P_AOJ: case P_SOJ: case P_SKIP:
		case P_SETZ: case P_SETO: case P_IOR: case P_LDB:
		    if (bb->Preg == b->Preg)
			b = NULL;	 /* unsafe rchange, flush */
		case P_TLN: case P_TDN: case P_TRN:
		case P_CAI: case P_CAM:
#if !SYS_CSI
		/*
		 * FEW, 2A(37) 22-Jul-92  It seems wrong to include these
		 * two instruction types in the "good" class, because they
		 * may jump off anywhere, to code that expects the MOVEM
		 * to have been done.  Ruling out these two instructon types
		 * resolves SPR 9574.
		 */

		case P_JUMP:
		case P_JRST:
#endif
		    continue;		/* safe or not, try again or break */
		default: b = NULL;	/* not one we know */
	    }
	if (b != NULL && sameaddr(b, previous, 0)) {
	    jumptoskip (q);		/* turn jump into skip */
	    p->Preg = previous->Preg = b->Preg;	/* set registers */
	    setskip(p);		/* P_MOVE is now skipped over */
	    b->Pop = P_NOP;		/* drop first P_MOVEM */
	    if (q->Pop == P_TRN+POF_ISSKIP+POS_SKPA && invskip (before (q)))
		q->Pop = P_NOP;		/* fold P_TRNA into previous */
	    else foldskip(q, 0);	/* else safely fold ex-P_JUMP */
	    return;
	}
    }					/* end if P_MOVE and P_MOVEM */

    /*
    ** fold:  (skips)
    **	      P_JRST lab
    **	      P_MOVE R,y
    **	      instr
    **
    ** into:  (inverse skips)
    **	      P_SKIPA R,y
    **	      P_TRNA
    **	      instr
    */

#if SYS_CSI		/*  Reg linkage */
    if (Register_Preserve (p->Preg)) /* avoid faulty opts */
        return;
#endif
    if (q->Pop != P_JRST || !newskip (p)) return;
    if (!invskip (before (q))) {
	unskip (p);			/* can't flip, undo changes */
	return;				/* and give up */
    }
    reflabel (lab, -1);			/* drop jump */
    setskip(p);				/* p skipped */
    q->Pop = P_TRN+POF_ISSKIP+POS_SKPA;		/* make P_TRNA */
    q->Ptype = PTA_ONEREG;			/* no mem ref */
    setskip(q);				/* q skipped */
    swappseudo (p, q);			/* swap P_TRNA and new P_SKIPA */
    setskip(previous);			/* previous skipped */

    if (!invskip (q)) return;		/* rest depends on flipping P_SKIPA */
    p->Pop = P_NOP;			/* if can flip, no P_TRNA */

    /*
    ** fold:  P_SKIPA R,x
    **        P_TDOA R,$BYTE
    **        P_IOR R,$BYTE
    **
    ** into:  P_MOVE R,x
    **	      P_IOR R,$BYTE
    */

    if (previous->Pop != P_IOR || (q = before (previous)) == NULL ||
	q->Pop != P_TDO+POF_ISSKIP+POS_SKPA || !sameaddr(q, previous, 0)) return;
    unskip(before(q));			/* turn prev skip off */
    q->Pop = P_NOP;			/* drop P_TDOA */
    clrskip(previous);			/* P_IOR not skipped over anymore */
}

/* UNJUMP(label) - Get rid of jump so can replace it with jumped-to label
**
** Only called once by CCGEN2's glogical().
**
** Called when we know there will only be one more instruction between
** here and the label, but we can't rely on later optimization because
** we want to emit another label here.
**
** Returns 1 or 0 depending on whether made successful skip.
** In neither case changes PTF_SKIPPED attribute of succeeding instrs.
*/

int
unjump(label lab)
{
    if (previous == NULL || previous->Pptr != lab) return 0;
    switch (previous->Pop & POF_OPCODE) {
    case P_JRST:
	dropjump(previous);		/* drop it all the way out */
	return 1;

    case P_JUMP:  case P_AOJ:  case P_SOJ:
	jumptoskip(previous);		/* make into P_CAIx */
	previous->Pop = revop(previous->Pop); /* with opposite parity */
	return 1;			/* let optlab() take care of rest */

    default:
	return 0;
    }
}

/* FOLDTRNA(p) - Attempt to get rid of a P_TRNA.
**
** Folds it into instructions ahead of it in the buffer.
** This is called late, by realcode(), to avoid confusion
** in earlier parts of the peepholer.
*/

int
foldtrna(PCODE *p)
{
    PCODE *q, *a;

    if (p == NULL
      || p->Pop != P_TRN+POF_ISSKIP+POS_SKPA
      || (q = after(p)) == NULL
      || (q->Pop != P_JRST
	&& q->Pop != P_POPJ
        && (q->Pop & POF_OPSKIP) != POS_SKPA)
      || (a = after(q)) == NULL
      || !newskip(a))
		return 0;		/* no good */

    /*
    ** fold:  TRNA
    ** 	       JRST  $x
    ** 	      MOVE  R,y
    **
    ** into:  SKIPA R,y
    ** 	       JRST  $x
    */

    unskip(q);				/* turn SKIPA over op into MOVE */
    setskip(a);				/* op that skipped TRNA now skips it */
    swappseudo(q, a);			/* switch the jump and new skip */
    p->Pop = P_NOP;			/* TRNA disappears */
    return 1;				/* tell realcode() we won */
}

/* INSKIP(p) - Fold test type instruction into previous P_SKIPA+P_MOVE
*/
void
inskip (PCODE *p)
{
    PCODE *q, *b;
    int skop, compl;

    if (p->Ptype != PTA_REGIS) return;	/* must be unskipped register op */

    switch (p->Pop) {			/* see what we want to fold back up */
    case P_AND: skop = P_TDZ; compl = 1; break; /* SKIPA+MOVE+AND => TDZA+AND */
    case P_IOR: skop = P_TDO; compl = 0; break; /* SKIPA+MOVE+IOR => TDOA+IOR */
    case P_XOR: skop = P_TDC; compl = 0; break; /* SKIPA+MOVE+XOR => TDCA+XOR */
    default: break;			/* can't handle anything else */
    }

    /* look for P_SKIPA and P_MOVE (with right registers) before op */
    /* we save the unsetz for last because it has side effects */
    if ((q = before (p)) == NULL || (q->Preg != p->Pr2 && q->Preg != p->Preg)
	|| (b = before (q)) == NULL || b->Pop != P_SKIP+POF_ISSKIP+POS_SKPA ||
(compl && b->Ptype != PTV_IMMED+PTF_SKIPPED) || b->Preg != q->Preg ||
	!unsetz (q)) return;

    /* found them, perform the fold */
    b->Pop = skop + POF_ISSKIP + POS_SKPA;	/* make always skipping op for P_SKIPA */
    if (b->Ptype & PTF_IMM) {		/* if immediate quantity */
	b->Ptype &=~ PTF_IMM;		/* make PTA_RCONST rather than PTV_IMMED */
	b->Pop = immedop (b->Pop);	/* and use built-in-immed op */
    }
    if (compl) b->Pvalue = ~ b->Pvalue;	/* complement mask if P_TDZA for P_AND */
    q->Pop = p->Pop;			/* and non-skip for P_MOVE (no compl) */

    /* see if result is already in right reg; if not, put it there */
    if (q->Preg == p->Pr2 || changereg (p->Preg, p->Pr2, before (b))) {
	b->Preg = q->Preg = p->Preg;	/* ok or fixed, change regs */
	dropinstr(p);			/* drop now useless op */
    } else {
	b->Preg = q->Preg = (char) (p->Pr2);	/* pre-op val in wrong reg, fix ops */ // FW KCC-NT
	p->Pop = P_MOVE;		/* add P_MOVE to put in right place */
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -