static OptFunc DOptAdd5 = { OptAdd5, "OptAdd5", 40, 0, 0, 0, 0, 0 };
static OptFunc DOptBoolTrans = { OptBoolTrans, "OptBoolTrans", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptBranchDist = { OptBranchDist, "OptBranchDist", 0, 0, 0, 0, 0, 0 };
-static OptFunc DOptCmp1 = { OptCmp1, "OptCmp1", 85, 0, 0, 0, 0, 0 };
-static OptFunc DOptCmp2 = { OptCmp2, "OptCmp2", 75, 0, 0, 0, 0, 0 };
+static OptFunc DOptCmp1 = { OptCmp1, "OptCmp1", 42, 0, 0, 0, 0, 0 };
+static OptFunc DOptCmp2 = { OptCmp2, "OptCmp2", 85, 0, 0, 0, 0, 0 };
static OptFunc DOptCmp3 = { OptCmp3, "OptCmp3", 75, 0, 0, 0, 0, 0 };
-static OptFunc DOptCmp4 = { OptCmp4, "OptCmp4", 100, 0, 0, 0, 0, 0 };
+static OptFunc DOptCmp4 = { OptCmp4, "OptCmp4", 75, 0, 0, 0, 0, 0 };
static OptFunc DOptCmp5 = { OptCmp5, "OptCmp5", 100, 0, 0, 0, 0, 0 };
-static OptFunc DOptCmp6 = { OptCmp6, "OptCmp6", 85, 0, 0, 0, 0, 0 };
-static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 50, 0, 0, 0, 0, 0 };
+static OptFunc DOptCmp6 = { OptCmp6, "OptCmp6", 100, 0, 0, 0, 0, 0 };
+static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 85, 0, 0, 0, 0, 0 };
+static OptFunc DOptCmp8 = { OptCmp8, "OptCmp8", 50, 0, 0, 0, 0, 0 };
static OptFunc DOptCondBranches = { OptCondBranches, "OptCondBranches", 80, 0, 0, 0, 0, 0 };
static OptFunc DOptDeadCode = { OptDeadCode, "OptDeadCode", 100, 0, 0, 0, 0, 0 };
static OptFunc DOptDeadJumps = { OptDeadJumps, "OptDeadJumps", 100, 0, 0, 0, 0, 0 };
&DOptCmp5,
&DOptCmp6,
&DOptCmp7,
+ &DOptCmp8,
&DOptCondBranches,
&DOptDeadCode,
&DOptDeadJumps,
C += RunOptFunc (S, &DOptCmp5, 1);
C += RunOptFunc (S, &DOptCmp6, 1);
C += RunOptFunc (S, &DOptCmp7, 1);
+ C += RunOptFunc (S, &DOptCmp8, 1);
C += RunOptFunc (S, &DOptTest1, 1);
C += RunOptFunc (S, &DOptLoad1, 1);
C += RunOptFunc (S, &DOptUnusedLoads, 1);
/* */
/* */
/* */
-/* (C) 2001-2003 Ullrich von Bassewitz */
+/* (C) 2001-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
unsigned OptCmp1 (CodeSeg* S)
+/* Search for the sequence
+ *
+ * ldx xx
+ * stx tmp1
+ * ora tmp1
+ *
+ * and replace it by
+ *
+ * ora xx
+ */
+{
+ unsigned Changes = 0;
+
+ /* Walk over the entries */
+ unsigned I = 0;
+ while (I < CS_GetEntryCount (S)) {
+
+ CodeEntry* L[3];
+
+ /* Get next entry */
+ L[0] = CS_GetEntry (S, I);
+
+ /* Check for the sequence */
+ if (L[0]->OPC == OP65_LDX &&
+ !CS_RangeHasLabel (S, I+1, 2) &&
+ CS_GetEntries (S, L+1, I+1, 2) &&
+ L[1]->OPC == OP65_STX &&
+ strcmp (L[1]->Arg, "tmp1") == 0 &&
+ L[2]->OPC == OP65_ORA &&
+ strcmp (L[2]->Arg, "tmp1") == 0) {
+
+ CodeEntry* X;
+
+ /* Insert the ora instead */
+ X = NewCodeEntry (OP65_ORA, L[0]->AM, L[0]->Arg, 0, L[0]->LI);
+ CS_InsertEntry (S, X, I);
+
+ /* Remove all other instructions */
+ CS_DelEntries (S, I+1, 3);
+
+ /* Remember, we had changes */
+ ++Changes;
+
+ }
+
+ /* Next entry */
+ ++I;
+
+ }
+
+ /* Return the number of changes made */
+ return Changes;
+}
+
+
+
+unsigned OptCmp2 (CodeSeg* S)
/* Search for the sequence
*
* stx xx
CodeEntry* E = CS_GetEntry (S, I);
/* Check for the sequence */
- if (E->OPC == OP65_STX &&
+ if (E->OPC == OP65_STX &&
!CS_RangeHasLabel (S, I+1, 2) &&
CS_GetEntries (S, L, I+1, 2) &&
- L[0]->OPC == OP65_STX &&
+ L[0]->OPC == OP65_STX &&
strcmp (L[0]->Arg, "tmp1") == 0 &&
- L[1]->OPC == OP65_ORA &&
+ L[1]->OPC == OP65_ORA &&
strcmp (L[1]->Arg, "tmp1") == 0) {
/* Remove the remaining instructions */
-unsigned OptCmp2 (CodeSeg* S)
+unsigned OptCmp3 (CodeSeg* S)
/* Search for
*
* lda/and/ora/eor ...
-unsigned OptCmp3 (CodeSeg* S)
+unsigned OptCmp4 (CodeSeg* S)
/* Search for
*
* lda x
-unsigned OptCmp4 (CodeSeg* S)
+unsigned OptCmp5 (CodeSeg* S)
/* Optimize compares of local variables:
*
* ldy #o
-unsigned OptCmp5 (CodeSeg* S)
+unsigned OptCmp6 (CodeSeg* S)
/* Search for calls to compare subroutines followed by a conditional branch
* and replace them by cheaper versions, since the branch means that the
* boolean value returned by these routines is not needed (we may also check
-unsigned OptCmp6 (CodeSeg* S)
+unsigned OptCmp7 (CodeSeg* S)
/* Search for a sequence ldx/txa/branch and remove the txa if A is not
* used later.
*/
-unsigned OptCmp7 (CodeSeg* S)
+unsigned OptCmp8 (CodeSeg* S)
/* Check for register compares where the contents of the register and therefore
* the result of the compare is known.
*/
/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 2001-2004 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
unsigned OptCmp1 (CodeSeg* S);
+/* Search for the sequence
+ *
+ * ldx xx
+ * stx tmp1
+ * ora tmp1
+ *
+ * and replace it by
+ *
+ * ora xx
+ */
+
+unsigned OptCmp2 (CodeSeg* S);
/* Search for the sequence
*
* stx xx
* ora xx
*/
-unsigned OptCmp2 (CodeSeg* S);
+unsigned OptCmp3 (CodeSeg* S);
/* Search for
*
* lda/and/ora/eor ...
* and remove the cmp.
*/
-unsigned OptCmp3 (CodeSeg* S);
+unsigned OptCmp4 (CodeSeg* S);
/* Search for
*
* lda x
* of this instruction.
*/
-unsigned OptCmp4 (CodeSeg* S);
+unsigned OptCmp5 (CodeSeg* S);
/* Optimize compares of local variables:
*
* ldy #o
* jne/jeq L2
*/
-unsigned OptCmp5 (CodeSeg* S);
+unsigned OptCmp6 (CodeSeg* S);
/* Search for calls to compare subroutines followed by a conditional branch
* and replace them by cheaper versions, since the branch means that the
* boolean value returned by these routines is not needed (we may also check
* that explicitly, but for the current code generator it is always true).
*/
-unsigned OptCmp6 (CodeSeg* S);
+unsigned OptCmp7 (CodeSeg* S);
/* Search for a sequence ldx/txa/branch and remove the txa if A is not
* used later.
*/
-unsigned OptCmp7 (CodeSeg* S);
+unsigned OptCmp8 (CodeSeg* S);
/* Check for register compares where the contents of the register and therefore
* the result of the compare is known.
*/