]> git.sur5r.net Git - cc65/commitdiff
65C02 additions, saved a few bytes in the code generator
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 14 Jun 2000 16:58:52 +0000 (16:58 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 14 Jun 2000 16:58:52 +0000 (16:58 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@80 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codegen.c
src/cc65/optimize.c

index 3704aebf50fd476d2e2190d670f623a84aba01d0..b7ed44fbf835935cabd3b724bfa2abd48c633780 100644 (file)
@@ -790,8 +790,12 @@ void g_getlocal (unsigned flags, int offs)
 
        case CF_CHAR:
            if ((flags & CF_FORCECHAR) || (flags & CF_TEST)) {
-               ldyconst (offs);
-                       AddCodeLine ("\tlda\t(sp),y");
+               if (CPU == CPU_65C02 && offs == 0) {
+                   AddCodeLine ("\tlda\t(sp)");
+               } else {
+                   ldyconst (offs);
+                   AddCodeLine ("\tlda\t(sp),y");
+               }
            } else {
                if (offs == 0) {
                    AddCodeLine ("\tldx\t#$00");
@@ -1004,8 +1008,12 @@ void g_putlocal (unsigned flags, int offs)
     switch (flags & CF_TYPE) {
 
        case CF_CHAR:
-                   ldyconst (offs);
-           AddCodeLine ("\tsta\t(sp),y");
+           if (CPU == CPU_65C02 && offs == 0) {
+               AddCodeLine ("\tsta\t(sp)");
+           } else {
+               ldyconst (offs);
+               AddCodeLine ("\tsta\t(sp),y");
+           }
            break;
 
        case CF_INT:
@@ -1275,35 +1283,35 @@ void g_scale (unsigned flags, long val)
                    if (flags & CF_FORCECHAR) {
                        while (p2--) {
                            AddCodeLine ("\tasl\ta");
-                       }
-                       break;
-                   }
-                   /* FALLTHROUGH */
-
-               case CF_INT:
-                   if (FavourSize || p2 >= 3) {
-                       if (flags & CF_UNSIGNED) {
-                           AddCodeLine ("\tjsr\tshlax%d", p2);
-                       } else {
-                           AddCodeLine ("\tjsr\taslax%d", p2);
-                       }
-                   } else {
-                       AddCodeLine ("\tstx\ttmp1");
-                       while (p2--) {
-                           AddCodeLine ("\tasl\ta");
-                           AddCodeLine ("\trol\ttmp1");
-                       }
-                       AddCodeLine ("\tldx\ttmp1");
-                   }
-                   break;
-
-               case CF_LONG:
-                   if (flags & CF_UNSIGNED) {
-                       AddCodeLine ("\tjsr\tshleax%d", p2);
-                   } else {
-                       AddCodeLine ("\tjsr\tasleax%d", p2);
-                   }
-                   break;
+                       }
+                       break;
+                   }
+                   /* FALLTHROUGH */
+
+               case CF_INT:
+                   if (FavourSize || p2 >= 3) {
+                       if (flags & CF_UNSIGNED) {
+                           AddCodeLine ("\tjsr\tshlax%d", p2);
+                       } else {
+                           AddCodeLine ("\tjsr\taslax%d", p2);
+                       }
+                   } else {
+                       AddCodeLine ("\tstx\ttmp1");
+                       while (p2--) {
+                           AddCodeLine ("\tasl\ta");
+                           AddCodeLine ("\trol\ttmp1");
+                       }
+                       AddCodeLine ("\tldx\ttmp1");
+                   }
+                   break;
+
+               case CF_LONG:
+                   if (flags & CF_UNSIGNED) {
+                       AddCodeLine ("\tjsr\tshleax%d", p2);
+                   } else {
+                       AddCodeLine ("\tjsr\tasleax%d", p2);
+                   }
+                   break;
 
                default:
                    typeerror (flags);
@@ -1348,7 +1356,7 @@ void g_scale (unsigned flags, long val)
                        } else {
                            AddCodeLine ("\tstx\ttmp1");
                            while (p2--) {
-                               AddCodeLine ("\tlsr\ttmp1");
+                               AddCodeLine ("\tlsr\ttmp1");
                                AddCodeLine ("\tror\ta");
                            }
                            AddCodeLine ("\tldx\ttmp1");
@@ -1393,7 +1401,7 @@ void g_scale (unsigned flags, long val)
 
 
 /*****************************************************************************/
-/*             Adds and subs of variables fix a fixed address               */
+/*             Adds and subs of variables fix a fixed address               */
 /*****************************************************************************/
 
 
@@ -1528,18 +1536,18 @@ void g_addeqstatic (unsigned flags, unsigned long label, unsigned offs,
                        if (flags & CF_CONST) {
                    if (val == 1) {
                        AddCodeLine ("\tinc\t%s", lbuf);
-                       AddCodeLine ("\tlda\t%s", lbuf);
-                   } else {
+                       AddCodeLine ("\tlda\t%s", lbuf);
+                   } else {
                                AddCodeLine ("\tlda\t#$%02X", val & 0xFF);
-                       AddCodeLine ("\tclc");
-                       AddCodeLine ("\tadc\t%s", lbuf);
-                       AddCodeLine ("\tsta\t%s", lbuf);
-                   }
+                       AddCodeLine ("\tclc");
+                       AddCodeLine ("\tadc\t%s", lbuf);
+                       AddCodeLine ("\tsta\t%s", lbuf);
+                   }
                        } else {
-                   AddCodeLine ("\tclc");
-                           AddCodeLine ("\tadc\t%s", lbuf);
-                   AddCodeLine ("\tsta\t%s", lbuf);
-                       }
+                   AddCodeLine ("\tclc");
+                           AddCodeLine ("\tadc\t%s", lbuf);
+                   AddCodeLine ("\tsta\t%s", lbuf);
+                       }
                if ((flags & CF_UNSIGNED) == 0) {
                    AddCodeLine ("\tbpl\t*+3");
                    AddCodeLine ("\tdex");
@@ -1584,9 +1592,9 @@ void g_addeqstatic (unsigned flags, unsigned long label, unsigned offs,
                        AddCodeLine ("\tsta\t%s", lbuf);
                        AddCodeLine ("\ttxa");
                        AddCodeLine ("\tadc\t%s+1", lbuf);
-                       AddCodeLine ("\tsta\t%s+1", lbuf);
-                       AddCodeLine ("\ttax");
-               AddCodeLine ("\tlda\t%s", lbuf);
+                       AddCodeLine ("\tsta\t%s+1", lbuf);
+                       AddCodeLine ("\ttax");
+               AddCodeLine ("\tlda\t%s", lbuf);
            }
                    break;
 
@@ -1634,38 +1642,38 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val)
 
                case CF_CHAR:
                    if (flags & CF_FORCECHAR) {
-                       if (offs == 0) {
-                           AddCodeLine ("\tldx\t#$00");
-                           if (flags & CF_CONST) {
-                               AddCodeLine ("\tclc");
+                       if (offs == 0) {
+                           AddCodeLine ("\tldx\t#$00");
+                           if (flags & CF_CONST) {
+                               AddCodeLine ("\tclc");
                                AddCodeLine ("\tlda\t#$%02X", val & 0xFF);
-                               AddCodeLine ("\tadc\t(sp,x)");
-                               AddCodeLine ("\tsta\t(sp,x)");
-                           } else {
-                               AddCodeLine ("\tclc");
-                               AddCodeLine ("\tadc\t(sp,x)");
-                               AddCodeLine ("\tsta\t(sp,x)");
-                           }
-                       } else {
-                           ldyconst (offs);
-                   AddCodeLine ("\tldx\t#$00");
-                   if (flags & CF_CONST) {
-                       AddCodeLine ("\tclc");
+                               AddCodeLine ("\tadc\t(sp,x)");
+                               AddCodeLine ("\tsta\t(sp,x)");
+                           } else {
+                               AddCodeLine ("\tclc");
+                               AddCodeLine ("\tadc\t(sp,x)");
+                               AddCodeLine ("\tsta\t(sp,x)");
+                           }
+                       } else {
+                           ldyconst (offs);
+                   AddCodeLine ("\tldx\t#$00");
+                   if (flags & CF_CONST) {
+                       AddCodeLine ("\tclc");
                                AddCodeLine ("\tlda\t#$%02X", val & 0xFF);
-                       AddCodeLine ("\tadc\t(sp),y");
-                       AddCodeLine ("\tsta\t(sp),y");
-                   } else {
+                       AddCodeLine ("\tadc\t(sp),y");
+                       AddCodeLine ("\tsta\t(sp),y");
+                   } else {
                        AddCodeLine ("\tclc");
-                       AddCodeLine ("\tadc\t(sp),y");
-                       AddCodeLine ("\tsta\t(sp),y");
-                   }
-               }
-               if ((flags & CF_UNSIGNED) == 0) {
-                   AddCodeLine ("\tbpl\t*+3");
-                   AddCodeLine ("\tdex");
-                   AddCodeHint ("x:!");        /* Invalidate X */
-               }
-                       break;
+                       AddCodeLine ("\tadc\t(sp),y");
+                       AddCodeLine ("\tsta\t(sp),y");
+                   }
+               }
+               if ((flags & CF_UNSIGNED) == 0) {
+                   AddCodeLine ("\tbpl\t*+3");
+                   AddCodeLine ("\tdex");
+                   AddCodeHint ("x:!");        /* Invalidate X */
+               }
+                       break;
                    }
                    /* FALLTHROUGH */
 
@@ -1674,10 +1682,10 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val)
                g_getimmed (flags, val, 0);
            }
            if (offs == 0) {
-               AddCodeLine ("\tjsr\taddeq0sp");
+               AddCodeLine ("\tjsr\taddeq0sp");
            } else {
-               ldyconst (offs);
-               AddCodeLine ("\tjsr\taddeqysp");
+               ldyconst (offs);
+               AddCodeLine ("\tjsr\taddeqysp");
            }
                    break;
 
@@ -1801,7 +1809,7 @@ void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs,
                            AddCodeLine ("\tbpl\t*+3");
                            AddCodeLine ("\tdex");
                            AddCodeHint ("x:!");                /* Invalidate X */
-                       }
+                       }
                        break;
                    }
                    /* FALLTHROUGH */
@@ -1846,7 +1854,7 @@ void g_subeqstatic (unsigned flags, unsigned long label, unsigned offs,
                    AddCodeLine ("\tsty\tptr1");
                    AddCodeLine ("\tldy\t#>(%s+1)", lbuf);
                    if (val == 1) {
-                       AddCodeLine ("\tjsr\tlsubeq1");
+                       AddCodeLine ("\tjsr\tlsubeq1");
                    } else {
                        AddCodeLine ("\tlda\t#$%02X", val & 0xFF);
                        AddCodeLine ("\tjsr\tlsubeqa");
@@ -1891,7 +1899,7 @@ void g_subeqlocal (unsigned flags, int offs, unsigned long val)
                    AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
                } else {
                    AddCodeLine ("\tsta\ttmp1");
-                   AddCodeLine ("\tlda\t(sp),y");
+                   AddCodeLine ("\tlda\t(sp),y");
                    AddCodeLine ("\tsbc\ttmp1");
                }
                        AddCodeLine ("\tsta\t(sp),y");
@@ -1981,7 +1989,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val)
                AddCodeLine ("\tlda\t(ptr1),y");
                AddCodeLine ("\tsbc\t#$%02X", (val >> 8) & 0xFF);
                AddCodeLine ("\tsta\t(ptr1),y");
-               AddCodeLine ("\ttax");
+               AddCodeLine ("\ttax");
                AddCodeLine ("\tpla");
                break;
            }
@@ -2296,7 +2304,7 @@ void g_push (unsigned flags, unsigned long val)
                break;
 
            case CF_LONG:
-               AddCodeLine ("\tjsr\tpusheax");
+               AddCodeLine ("\tjsr\tpusheax");
                break;
 
            default:
@@ -2521,7 +2529,7 @@ void g_mul (unsigned flags, unsigned long val)
 {
     static char* ops [12] = {
        0,              "tosmula0",     "tosmulax",
-       0,              "tosumula0",    "tosumulax",
+       0,              "tosumula0",    "tosumulax",
        0,              0,              "tosmuleax",
        0,              0,              "tosumuleax",
     };
@@ -2566,7 +2574,7 @@ void g_mul (unsigned flags, unsigned long val)
                            AddCodeLine ("\tsta\ttmp1");
                            AddCodeLine ("\tasl\ta");
                            AddCodeLine ("\tasl\ta");
-                           AddCodeLine ("\tclc");
+                           AddCodeLine ("\tclc");
                            AddCodeLine ("\tadc\ttmp1");
                            AddCodeLine ("\tasl\ta");
                            return;
@@ -2746,7 +2754,7 @@ void g_xor (unsigned flags, unsigned long val)
                    return;
                } else if ((val & 0xFF) == 0) {
                    AddCodeLine ("\tpha");
-                   AddCodeLine ("\ttxa");
+                   AddCodeLine ("\ttxa");
                    AddCodeLine ("\teor\t#$%02X", (val >> 8) & 0xFF);
                    AddCodeLine ("\ttax");
                    AddCodeLine ("\tpla");
@@ -2836,7 +2844,7 @@ void g_and (unsigned flags, unsigned long val)
                if (val <= 0xFF) {
                    ldxconst (0);
                    AddCodeLine ("\tstx\tsreg+1");
-                   AddCodeLine ("\tstx\tsreg");
+                   AddCodeLine ("\tstx\tsreg");
                    if ((val & 0xFF) != 0xFF) {
                         AddCodeLine ("\tand\t#$%02X", val & 0xFF);
                    }
@@ -2926,7 +2934,7 @@ void g_asr (unsigned flags, unsigned long val)
                    AddCodeLine ("\tlda\tsreg");
                    AddCodeLine ("\tsty\tsreg+1");
                    AddCodeLine ("\tsty\tsreg");
-                   return;
+                   return;
                }
                break;
 
@@ -2971,7 +2979,7 @@ void g_asl (unsigned flags, unsigned long val)
                    if (flags & CF_UNSIGNED) {
                        AddCodeLine ("\tjsr\tshlax%ld", val);
                    } else {
-                       AddCodeLine ("\tjsr\taslax%ld", val);
+                       AddCodeLine ("\tjsr\taslax%ld", val);
                    }
                    return;
                } else if (val == 8) {
@@ -3106,7 +3114,7 @@ void g_inc (unsigned flags, unsigned long val)
                    while (val--) {
                        AddCodeLine ("\tina");
                    }
-               } else {
+               } else {
                    AddCodeLine ("\tclc");
                    AddCodeLine ("\tadc\t#$%02X", val & 0xFF);
                }
@@ -3151,7 +3159,7 @@ void g_inc (unsigned flags, unsigned long val)
                } else {
                    AddCodeLine ("\tclc");
                    if ((val & 0xFF) != 0) {
-                       AddCodeLine ("\tadc\t#$%02X", (unsigned char) val);
+                       AddCodeLine ("\tadc\t#$%02X", (unsigned char) val);
                        /* Tell the optimizer that the X register may be invalid */
                        AddCodeHint ("x:!");
                    }
@@ -3196,7 +3204,7 @@ void g_dec (unsigned flags, unsigned long val)
                    }
                } else {
                    AddCodeLine ("\tsec");
-                   AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
+                   AddCodeLine ("\tsbc\t#$%02X", val & 0xFF);
                }
                break;
            }
@@ -3376,7 +3384,7 @@ void g_lt (unsigned flags, unsigned long val)
                    }
                    return;
                }
-               /* FALLTHROUGH */
+               /* FALLTHROUGH */
 
            case CF_INT:
                if ((flags & CF_UNSIGNED) == 0 && val == 0) {
@@ -3511,7 +3519,7 @@ void g_gt (unsigned flags, unsigned long val)
                            AddCodeLine ("\tjsr\tboolne");
                        }
                    } else {
-                       AddCodeLine ("\tjsr\tboolgt");
+                       AddCodeLine ("\tjsr\tboolgt");
                    }
                    return;
                }
@@ -3601,7 +3609,7 @@ void g_ge (unsigned flags, unsigned long val)
                    AddCodeLine ("\tjsr\tbooluge");
                    return;
                }
-               break;
+               break;
 
            case CF_LONG:
                break;
@@ -3646,7 +3654,7 @@ void g_defdata (unsigned flags, unsigned long val, unsigned offs)
        switch (flags & CF_TYPE) {
 
            case CF_CHAR:
-               AddCodeLine ("\t.byte\t$%02lX", val & 0xFF);
+               AddCodeLine ("\t.byte\t$%02lX", val & 0xFF);
                break;
 
            case CF_INT:
@@ -3715,10 +3723,10 @@ void g_zerobytes (unsigned n)
     AddCodeLine ("\t.res\t%u,$00", n);
 }
 
-
+                              
 
 /*****************************************************************************/
-/*                         Inlined known functions                          */
+/*                         Inlined known functions                          */
 /*****************************************************************************/
 
 
@@ -3741,8 +3749,8 @@ void g_strlen (unsigned flags, unsigned long val, unsigned offs)
        AddCodeLine ("\tiny");
        AddCodeLine ("\tlda\t%s,y", lbuf);
        AddCodeLine ("\tbne\tL%04X", label);
+               AddCodeLine ("\ttax");
        AddCodeLine ("\ttya");
-       AddCodeLine ("\tldx\t#$00");
 
     } else {
 
@@ -3759,8 +3767,8 @@ void g_strlen (unsigned flags, unsigned long val, unsigned offs)
            AddCodeLine ("\tiny");
            AddCodeLine ("\tlda\t(ptr1),y");
            AddCodeLine ("\tbne\tL%04X", label);
+                   AddCodeLine ("\ttax");
            AddCodeLine ("\ttya");
-           AddCodeLine ("\tldx\t#$00");
        }
     }
 }
index 8302ebdc2bb2905c2d707a64ad1ac375ee64fb4c..dce39dbac5956c5b739db30d6af0093db6d50005 100644 (file)
@@ -1103,7 +1103,7 @@ static unsigned RVUInt2 (Line* L,
        do {
 
            /* Handle jumps to local labels (continue there) */
-                   if (LineMatch (L, "\tjmp\tL")) {
+                   if (LineMatch (L, "\tjmp\tL") || LineMatch (L, "\tbra\tL")) {
                /* Get the target of the jump */
                L = GetTargetLine (L->Line+5);
            }
@@ -1113,33 +1113,33 @@ static unsigned RVUInt2 (Line* L,
 
            /* Bail out if we're done */
            if (L == 0 || IsLabel (L)) {
-               /* Something is wrong */
-               return REG_ALL;
+               /* Something is wrong */
+               return REG_ALL;
            }
 
            /* Check if we had this line already. If so, bail out, if not,
             * add it to the list of known lines.
             */
            if (LCHasLine (LC, L) || !LCAddLine (LC, L)) {
-               goto ExitPoint;
+               goto ExitPoint;
            }
 
-       } while (LineMatch (L, "\tjmp\tL"));
+       } while (LineMatch (L, "\tjmp\tL") || LineMatch (L, "\tbra\tL"));
 
        /* Special handling for branches */
        if (LineMatchX (L, ShortBranches) >= 0 ||
            LineMatchX (L, LongBranches) >= 0) {
            const char* Target = L->Line+5;
            if (Target[0] == 'L') {
-               /* Jump to local label. Check the register usage starting at
-                * the branch target and at the code following the branch.
-                * All registers that are unused in both execution flows are
-                * returned as unused.
-                */
-               unsigned U1, U2;
+               /* Jump to local label. Check the register usage starting at
+                * the branch target and at the code following the branch.
+                * All registers that are unused in both execution flows are
+                * returned as unused.
+                */
+               unsigned U1, U2;
                        U2 = RVUInt1 (GetTargetLine (Target), LC, Used, Unused);
-               U1 = RVUInt1 (L, LC, Used, Unused);
-               return U1 | U2;         /* Used in any of the branches */
+               U1 = RVUInt1 (L, LC, Used, Unused);
+               return U1 | U2;         /* Used in any of the branches */
            }
        }
 
@@ -1218,7 +1218,7 @@ static unsigned RegValUsed (Line* Start)
  * If the end of the lookahead is reached, all registers that are uncertain
  * are marked as used.
  * The result of the search is returned.
- */
+ */                                                            
 {
     unsigned R;
 
@@ -1758,7 +1758,7 @@ static void OptRegLoads (void)
 
            /* Search for a load of Y and check if the value is used later */
            else if (LineMatch (L, "\tldy\t")           &&
-                              !RegYUsed (L)                    &&
+                              !RegYUsed (L)                    &&
                       !IsCondJump (NextInstruction (L))) {
 
                /* Remember to delete this line */
@@ -3867,6 +3867,10 @@ static Line* OptOneBlock (Line* L)
        } else if (LineFullMatch (L, "\tjsr\tpushax")) {
            /* We know about this function */
            Y = 1;
+       } else if (LineFullMatch (L, "\tjsr\tpushaysp")) {
+           /* We know about this function */
+           A = -1;
+           Y = 0;
        } else if (LineFullMatch (L, "\tjsr\tpushc0")) {
            /* We know about this function */
            A = 0;
@@ -4196,6 +4200,26 @@ static void OptJumps (void)
        }
        L = NextCodeLine (L);
     }
+
+    /* Special treatment for jumps on the 65C02 */
+    if (CPU == CPU_65C02) {
+
+       Line* L = FirstCode;
+       while (L) {
+           if (LineMatch (L, "\tjmp\tL")) {
+               Line* Target = GetTargetLine (L->Line+5);
+               unsigned Distance = GetJumpDistance (L, Target);
+               if (Distance < 123) {           /* Safety */
+                           L->Line [1] = 'b';          /* Make a short branch */
+                   L->Line [2] = 'r';
+                   L->Line [3] = 'a';
+                   L->Size = 2;                /* Set new size */
+               }
+           }
+           L = NextCodeLine (L);
+       }
+
+    }
 }