Пример #1
0
unsigned OptSub2 (CodeSeg* S)
/* Search for the sequence
**
**      lda     xx
**      sec
**      sta     tmp1
**      lda     yy
**      sbc     tmp1
**      sta     yy
**
** and replace it by
**
**      sec
**      lda     yy
**      sbc     xx
**      sta     yy
*/
{
    unsigned Changes = 0;

    /* Walk over the entries */
    unsigned I = 0;
    while (I < CS_GetEntryCount (S)) {

        CodeEntry* L[5];

        /* Get next entry */
        CodeEntry* E = CS_GetEntry (S, I);

        /* Check for the sequence */
        if (E->OPC == OP65_LDA                             &&
            !CS_RangeHasLabel (S, I+1, 5)                  &&
            CS_GetEntries (S, L, I+1, 5)                   &&
            L[0]->OPC == OP65_SEC                          &&
            L[1]->OPC == OP65_STA                          &&
            strcmp (L[1]->Arg, "tmp1") == 0                &&
            L[2]->OPC == OP65_LDA                          &&
            L[3]->OPC == OP65_SBC                          &&
            strcmp (L[3]->Arg, "tmp1") == 0                &&
            L[4]->OPC == OP65_STA                          &&
            strcmp (L[4]->Arg, L[2]->Arg) == 0) {

            /* Remove the store to tmp1 */
            CS_DelEntry (S, I+2);

            /* Remove the subtraction */
            CS_DelEntry (S, I+3);

            /* Move the lda to the position of the subtraction and change the
            ** op to SBC.
            */
            CS_MoveEntry (S, I, I+3);
            CE_ReplaceOPC (E, OP65_SBC);

            /* If the sequence head had a label, move this label back to the
            ** head.
            */
            if (CE_HasLabel (E)) {
                CS_MoveLabels (S, E, L[0]);
            }

            /* Remember, we had changes */
            ++Changes;

        }

        /* Next entry */
        ++I;

    }

    /* Return the number of changes made */
    return Changes;
}
Пример #2
0
unsigned OptCmp4 (CodeSeg* S)
/* Search for
 *
 *  	lda	x
 *  	ldx	y
 *  	cpx 	#a
 *  	bne 	L1
 *  	cmp 	#b
 * L1: 	jne/jeq	L2
 *
 * If a is zero, we may remove the compare. If a and b are both zero, we may
 * replace it by the sequence
 *
 *  	lda 	x
 *  	ora 	x+1
 *  	jne/jeq ...
 *
 * L1 may be either the label at the branch instruction, or the target label
 * of this instruction.
 */
{
    unsigned Changes = 0;

    /* Walk over the entries */
    unsigned I = 0;
    while (I < CS_GetEntryCount (S)) {

	CodeEntry* L[5];

      	/* Get next entry */
       	CodeEntry* E = CS_GetEntry (S, I);

     	/* Check for the sequence */
       	if (E->OPC == OP65_LDA               &&
	    CS_GetEntries (S, L, I+1, 5)     &&
	    L[0]->OPC == OP65_LDX            &&
	    !CE_HasLabel (L[0])              &&
      	    IsImmCmp16 (L+1)                 &&
	    !RegAXUsed (S, I+6)) {

      	    if ((L[4]->Info & OF_FBRA) != 0 && L[1]->Num == 0 && L[3]->Num == 0) {
		/* The value is zero, we may use the simple code version. */
		CE_ReplaceOPC (L[0], OP65_ORA);
		CS_DelEntries (S, I+2, 3);
       	    } else {
		/* Move the lda instruction after the first branch. This will
		 * improve speed, since the load is delayed after the first
		 * test.
		 */
		CS_MoveEntry (S, I, I+4);

		/* We will replace the ldx/cpx by lda/cmp */
	    	CE_ReplaceOPC (L[0], OP65_LDA);
		CE_ReplaceOPC (L[1], OP65_CMP);

		/* Beware: If the first LDA instruction had a label, we have
	     	 * to move this label to the top of the sequence again.
		 */
		if (CE_HasLabel (E)) {
		    CS_MoveLabels (S, E, L[0]);
		}

	    }

	    ++Changes;
	}

	/* Next entry */
	++I;

    }

    /* Return the number of changes made */
    return Changes;
}