]> git.sur5r.net Git - cc65/commitdiff
Added new code hints for use at the end of a function
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 4 Dec 2000 22:28:15 +0000 (22:28 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 4 Dec 2000 22:28:15 +0000 (22:28 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@552 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codegen.c
src/cc65/function.c
src/cc65/optimize.c
src/cc65/stmt.c

index 3d1bd3ffdf5edc70eae9d25f1850006a2d24f6f3..3afcc25b2e26c3252fe7d2556d15c84bd2fb5e9e 100644 (file)
@@ -485,6 +485,12 @@ void g_leave (int flags, int val)
     int k;
     char buf [40];
 
+    /* CF_REG is set if we're returning a value from the function */
+    if ((flags & CF_REG) == 0) {
+       AddCodeHint ("x:-");
+       AddCodeHint ("a:-");
+    }
+
     /* How many bytes of locals do we have to drop? */
     k = -oursp;
 
@@ -499,8 +505,10 @@ void g_leave (int flags, int val)
        /* Drop stackframe or leave with rts */
        k += funcargs;
        if (k == 0) {
+           AddCodeHint ("y:-");        /* Y register no longer used */
            AddCodeLine ("\trts");
        } else if (k <= 8) {
+           AddCodeHint ("y:-");        /* Y register no longer used */
            AddCodeLine ("\tjmp\tincsp%d", k);
        } else {
            CheckLocalOffs (k);
@@ -515,7 +523,10 @@ void g_leave (int flags, int val)
            /* We've a stack frame to drop */
            ldyconst (k);
            strcat (buf, "y");
-       }
+       } else {
+           /* Y register no longer used */
+           AddCodeHint ("y:-");        
+       }
        if (flags & CF_CONST) {
            if ((flags & CF_TYPE) != CF_LONG) {
                /* Constant int sized value given for return code */
index 91888fabf89517ce9575bec80d6dc1cc9ee87881..393679b778492f8a190111783a18039fd5b7c182 100644 (file)
@@ -198,6 +198,7 @@ void NewFunc (SymEntry* Func)
 /* Parse argument declarations and function body. */
 {
     int isbrk;
+    unsigned Flags;
 
     /* Get the function descriptor from the function entry */
     FuncDesc* D = DecodePtr (Func->Type+1);
@@ -251,7 +252,9 @@ void NewFunc (SymEntry* Func)
        }
 #endif
        RestoreRegVars (0);
-        g_leave (CF_NONE, 0);
+
+       Flags = HasVoidReturn (CurrentFunc)? CF_NONE : CF_REG;
+        g_leave (Flags, 0);                                  
     }
 
     /* Dump literal data created by the function */
index ed4dc334aa607c76747e887b1dc4f9549bbb44f9..1cb57894b6c2f11c7ad3c0479a37736226fd8cc1 100644 (file)
@@ -461,7 +461,7 @@ static void FreeLines (Line* Start, Line* End)
 
 
 /*****************************************************************************/
-/*                          Line Collections                                */
+/*                          Line Collections                                */
 /*****************************************************************************/
 
 
@@ -536,6 +536,14 @@ static int IsLocalLabel (const Line* L)
 
 
 
+static int IsExtLabel (const Line* L)
+/* Return true if the line is an external label line */
+{
+    return (L->Line [0] == '_');
+}
+
+
+
 static int IsLabel (const Line* L)
 /* Return true if the line is a label line */
 {
@@ -1136,13 +1144,15 @@ static unsigned RVUInt2 (Line* L,
                L = GetTargetLine (L->Line+5);
            }
 
-           /* Get the next instruction line */
-                   L = NextInstruction (L);
+           /* Get the next line, skip local labels */
+           do {
+                       L = NextCodeSegLine (L);
+           } while (L && (IsLocalLabel (L) || L->Line[0] == '\0'));
 
            /* Bail out if we're done */
-           if (L == 0 || IsLabel (L)) {
-               /* Something is wrong */
-               return REG_ALL;
+           if (L == 0 || IsExtLabel (L)) {
+               /* End of function reached */
+               goto ExitPoint;
            }
 
            /* Check if we had this line already. If so, bail out, if not,
@@ -1154,55 +1164,68 @@ static unsigned RVUInt2 (Line* L,
 
        } while (LineMatch (L, "\tjmp\tL") || LineMatch (L, "\tbra\tL"));
 
+       /* Special handling of code hints */
+               if (IsHintLine (L)) {
+
+           if (IsHint (L, "a:-") && (Used & REG_A) == 0) {
+               Unused |= REG_A;
+           } else if (IsHint (L, "x:-") && (Used & REG_X) == 0) {
+               Unused |= REG_X;
+           } else if (IsHint (L, "y:-") && (Used & REG_Y) == 0) {
+               Unused |= REG_Y;
+           }
+
        /* Special handling for branches */
-       if (LineMatchX (L, ShortBranches) >= 0 ||
+       } else 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 */
            }
-       }
+       } else {
 
-       /* Search for the instruction in this line */
-       I = FindCmd (L);
+           /* Search for the instruction in this line */
+           I = FindCmd (L);
 
-       /* If we don't find it, assume all other registers are */
-       if (I < 0) {
-           break;
-       }
+           /* If we don't find it, assume all other registers are used */
+           if (I < 0) {
+               break;
+           }
 
-       /* Evaluate the use flags, check for addressing modes */
-       R = CmdDesc[I].Use;
-       if (IsXAddrMode (L)) {
-           R |= REG_X;
-       } else if (IsYAddrMode (L)) {
-           R |= REG_Y;
-       }
-       if (R) {
-           /* Remove registers that were already new loaded */
-           R &= ~Unused;
+           /* Evaluate the use flags, check for addressing modes */
+           R = CmdDesc[I].Use;
+           if (IsXAddrMode (L)) {
+               R |= REG_X;
+           } else if (IsYAddrMode (L)) {
+               R |= REG_Y;
+           }
+           if (R) {
+               /* Remove registers that were already new loaded */
+               R &= ~Unused;
 
-           /* Remember the remaining registers */
-           Used |= R;
-       }
+               /* Remember the remaining registers */
+               Used |= R;
+           }
 
-       /* Evaluate the load flags */
-       R = CmdDesc[I].Load;
-       if (R) {
-           /* Remove registers that were already used */
-           R &= ~Used;
+           /* Evaluate the load flags */
+           R = CmdDesc[I].Load;
+           if (R) {
+               /* Remove registers that were already used */
+               R &= ~Used;
 
-           /* Remember the remaining registers */
-           Unused |= R;
-               }
+               /* Remember the remaining registers */
+               Unused |= R;
+           }
+
+       }
 
                /* If we know about all registers, bail out */
                if ((Used | Unused) == REG_ALL) {
index eda5c143346e880665c37f72c0ef446b4be8beec..5a1ec4a9cef4da87c65926b8f3afad6bbe57d8d2 100644 (file)
@@ -166,7 +166,7 @@ static void doreturn (void)
 /* Handle 'return' statement here */
 {
     struct expent lval;
-    unsigned etype = 0;                /* Type of return expression */
+    unsigned Flags = 0;                /* Code generator flags */
     int HaveVal = 0;           /* Do we have a return value in ax? */
 
 
@@ -177,21 +177,21 @@ static void doreturn (void)
                }
                if (evalexpr (CF_NONE, hie0, &lval) == 0) {
                    /* Constant value */
-                   etype = CF_CONST;
+                   Flags = CF_CONST;
                } else {
-           /* Value in the primary register */
-           HaveVal = 1;
-       }
+           /* Value in the primary register */
+           HaveVal = 1;
+       }
 
-       /* Convert the return value to the type of the function result */
-       if (!HasVoidReturn (CurrentFunc)) {
-                   etype |= assignadjust (GetReturnType (CurrentFunc), &lval) & ~CF_CONST;
-       }
+       /* Convert the return value to the type of the function result */
+       if (!HasVoidReturn (CurrentFunc)) {
+                   Flags |= (assignadjust (GetReturnType (CurrentFunc), &lval) & ~CF_CONST) | CF_REG;
+       }
     } else if (!HasVoidReturn (CurrentFunc)) {
-       Error ("Function `%s' must return a value", GetFuncName (CurrentFunc));
+       Error ("Function `%s' must return a value", GetFuncName (CurrentFunc));
     }
     RestoreRegVars (HaveVal);
-    g_leave (etype, lval.e_const);
+    g_leave (Flags, lval.e_const);
 }
 
 
@@ -396,7 +396,7 @@ static void cascadeswitch (struct expent* eval)
                            CodeLab = GetLabel ();
                        }
                        g_jump (CodeLab);
-                   }              
+                   }
 
                    /* Remember that we had a default label */
                    HaveDefault = 1;