]> git.sur5r.net Git - cc65/blobdiff - src/cc65/coptcmp.c
Fixed a bug in signed int compares
[cc65] / src / cc65 / coptcmp.c
index a88e7047d1fdfe58e9e9c96babd797bbbe6c1c3d..91f929b5d8473f43f33a9b5bb27aaf7454bb2bf3 100644 (file)
@@ -6,9 +6,9 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
+/* (C) 2001-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 
 
 
-/* Defines for the conditions in a compare */
-typedef enum {
-    CMP_INV = -1,
-    CMP_EQ,
-    CMP_NE,
-    CMP_GT,
-    CMP_GE,
-    CMP_LT,
-    CMP_LE,
-    CMP_UGT,
-    CMP_UGE,
-    CMP_ULT,
-    CMP_ULE
-} cmp_t;
-
-/* Table with the compare suffixes */
-static const char CmpSuffixTab [][4] = {
-    "eq", "ne", "gt", "ge", "lt", "le", "ugt", "uge", "ult", "ule"
-};
-
 /* Table used to invert a condition, indexed by condition */
 static const unsigned char CmpInvertTab [] = {
     CMP_NE, CMP_EQ,
@@ -89,59 +69,6 @@ static const char CmpSignedTab [] = {
 
 
 
-static cmp_t FindCmpCond (const char* Code, unsigned CodeLen)
-/* Search for a compare condition by the given code using the given length */
-{
-    unsigned I;
-
-    /* Linear search */
-    for (I = 0; I < sizeof (CmpSuffixTab) / sizeof (CmpSuffixTab [0]); ++I) {
-       if (strncmp (Code, CmpSuffixTab [I], CodeLen) == 0) {
-           /* Found */
-           return I;
-       }
-    }
-
-    /* Not found */
-    return CMP_INV;
-}
-
-
-
-static cmp_t FindBoolCmpCond (const char* Name)
-/* Map a condition suffix to a code. Return the code or CMP_INV on failure */
-{
-    /* Check for the correct subroutine name */
-    if (strncmp (Name, "bool", 4) == 0) {
-       /* Name is ok, search for the code in the table */
-       return FindCmpCond (Name+4, strlen(Name)-4);
-    } else {
-       /* Not found */
-       return CMP_INV;
-    }
-}
-
-
-
-static cmp_t FindTosCmpCond (const char* Name)
-/* Check if this is a call to one of the TOS compare functions (tosgtax).
- * Return the condition code or CMP_INV on failure.
- */
-{
-    unsigned Len = strlen (Name);
-
-    /* Check for the correct subroutine name */
-    if (strncmp (Name, "tos", 3) == 0 && strcmp (Name+Len-2, "ax") == 0) {
-       /* Name is ok, search for the code in the table */
-       return FindCmpCond (Name+3, Len-3-2);
-    } else {
-       /* Not found */
-       return CMP_INV;
-    }
-}
-
-
-
 static void ReplaceCmp (CodeSeg* S, unsigned I, cmp_t Cond)
 /* Helper function for the replacement of routines that return a boolean
  * followed by a conditional jump. Instead of the boolean value, the condition
@@ -309,7 +236,7 @@ unsigned OptBoolTrans (CodeSeg* S)
        /* Check for a boolean transformer */
        if (E->OPC == OP65_JSR                           &&
            (Cond = FindBoolCmpCond (E->Arg)) != CMP_INV &&
-           (N = CS_GetNextEntry (S, I)) != 0        &&
+           (N = CS_GetNextEntry (S, I)) != 0            &&
            (N->Info & OF_ZBRA) != 0) {
 
            /* Make the boolean transformer unnecessary by changing the
@@ -379,7 +306,7 @@ unsigned OptCmp1 (CodeSeg* S)
                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               &&
            strcmp (L[1]->Arg, "tmp1") == 0) {
@@ -434,22 +361,24 @@ unsigned OptCmp2 (CodeSeg* S)
        /* Check for the sequence */
                if ((L[0]->OPC == OP65_ADC ||
                     L[0]->OPC == OP65_AND ||
+             L[0]->OPC == OP65_ASL ||
                     L[0]->OPC == OP65_DEA ||
                     L[0]->OPC == OP65_EOR ||
                     L[0]->OPC == OP65_INA ||
                     L[0]->OPC == OP65_LDA ||
+             L[0]->OPC == OP65_LSR ||
                     L[0]->OPC == OP65_ORA ||
                     L[0]->OPC == OP65_PLA ||
                     L[0]->OPC == OP65_SBC ||
                     L[0]->OPC == OP65_TXA ||
                     L[0]->OPC == OP65_TYA)         &&
            !CS_RangeHasLabel (S, I+1, 2)   &&
-           CS_GetEntries (S, L+1, I+1, 2)   &&
+           CS_GetEntries (S, L+1, I+1, 2)  &&
            L[1]->OPC == OP65_CMP           &&
            CE_KnownImm (L[1])              &&
            L[1]->Num == 0) {
 
-           /* Check for the call to boolxx. We cannot remove the compare if
+           /* Check for the call to boolxx. We only remove the compare if
             * the carry flag is evaluated later, because the load will not
             * set the carry flag.
             */
@@ -631,7 +560,7 @@ unsigned OptCmp4 (CodeSeg* S)
            CE_KnownImm (L[0])              &&
            CS_GetEntries (S, L+1, I+1, 5)  &&
            !CE_HasLabel (L[1])             &&
-           CE_IsCall (L[1], "ldaxysp")     &&
+           CE_IsCallTo (L[1], "ldaxysp")   &&
            IsImmCmp16 (L+2)) {
 
                    if ((L[5]->Info & OF_FBRA) != 0 && L[2]->Num == 0 && L[4]->Num == 0) {
@@ -670,17 +599,16 @@ unsigned OptCmp4 (CodeSeg* S)
                /* Change the code to just use the A register. Move the load
                 * of the low byte after the first branch if possible:
                 *
-                *      ldy     #o-1
+                *      ldy     #o
                 *      lda     (sp),y
                 *      cmp     #a
                 *      bne     L1
-                *      ldy     #o
+                *      ldy     #o-1
                 *      lda     (sp),y
                 *      cmp     #b
                 *      jne/jeq ...
                 */
-               sprintf (Buf, "$%02X", (int)(L[0]->Num-1));
-               X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
+               X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI);
                CS_InsertEntry (S, X, I+3);
 
                X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);
@@ -689,7 +617,8 @@ unsigned OptCmp4 (CodeSeg* S)
                X = NewCodeEntry (OP65_CMP, L[2]->AM, L[2]->Arg, 0, L[2]->LI);
                CS_InsertEntry (S, X, I+5);
 
-               X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI);
+               sprintf (Buf, "$%02X", (int)(L[0]->Num-1));
+               X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[0]->LI);
                CS_InsertEntry (S, X, I+7);
 
                X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "sp", 0, L[1]->LI);