Added new code hints for use at the end of a function

git-svn-id: svn://svn.cc65.org/cc65/trunk@552 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2000-12-04 22:28:15 +00:00
parent a05a5e5c38
commit c8171988a2
4 changed files with 99 additions and 62 deletions

View File

@@ -485,6 +485,12 @@ void g_leave (int flags, int val)
int k; int k;
char buf [40]; 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? */ /* How many bytes of locals do we have to drop? */
k = -oursp; k = -oursp;
@@ -499,8 +505,10 @@ void g_leave (int flags, int val)
/* Drop stackframe or leave with rts */ /* Drop stackframe or leave with rts */
k += funcargs; k += funcargs;
if (k == 0) { if (k == 0) {
AddCodeHint ("y:-"); /* Y register no longer used */
AddCodeLine ("\trts"); AddCodeLine ("\trts");
} else if (k <= 8) { } else if (k <= 8) {
AddCodeHint ("y:-"); /* Y register no longer used */
AddCodeLine ("\tjmp\tincsp%d", k); AddCodeLine ("\tjmp\tincsp%d", k);
} else { } else {
CheckLocalOffs (k); CheckLocalOffs (k);
@@ -515,6 +523,9 @@ void g_leave (int flags, int val)
/* We've a stack frame to drop */ /* We've a stack frame to drop */
ldyconst (k); ldyconst (k);
strcat (buf, "y"); strcat (buf, "y");
} else {
/* Y register no longer used */
AddCodeHint ("y:-");
} }
if (flags & CF_CONST) { if (flags & CF_CONST) {
if ((flags & CF_TYPE) != CF_LONG) { if ((flags & CF_TYPE) != CF_LONG) {

View File

@@ -198,6 +198,7 @@ void NewFunc (SymEntry* Func)
/* Parse argument declarations and function body. */ /* Parse argument declarations and function body. */
{ {
int isbrk; int isbrk;
unsigned Flags;
/* Get the function descriptor from the function entry */ /* Get the function descriptor from the function entry */
FuncDesc* D = DecodePtr (Func->Type+1); FuncDesc* D = DecodePtr (Func->Type+1);
@@ -251,7 +252,9 @@ void NewFunc (SymEntry* Func)
} }
#endif #endif
RestoreRegVars (0); 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 */ /* Dump literal data created by the function */

View File

@@ -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) static int IsLabel (const Line* L)
/* Return true if the line is a label line */ /* Return true if the line is a label line */
{ {
@@ -1136,13 +1144,15 @@ static unsigned RVUInt2 (Line* L,
L = GetTargetLine (L->Line+5); L = GetTargetLine (L->Line+5);
} }
/* Get the next instruction line */ /* Get the next line, skip local labels */
L = NextInstruction (L); do {
L = NextCodeSegLine (L);
} while (L && (IsLocalLabel (L) || L->Line[0] == '\0'));
/* Bail out if we're done */ /* Bail out if we're done */
if (L == 0 || IsLabel (L)) { if (L == 0 || IsExtLabel (L)) {
/* Something is wrong */ /* End of function reached */
return REG_ALL; goto ExitPoint;
} }
/* Check if we had this line already. If so, bail out, if not, /* Check if we had this line already. If so, bail out, if not,
@@ -1154,8 +1164,19 @@ static unsigned RVUInt2 (Line* L,
} while (LineMatch (L, "\tjmp\tL") || LineMatch (L, "\tbra\tL")); } 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 */ /* Special handling for branches */
if (LineMatchX (L, ShortBranches) >= 0 || } else if (LineMatchX (L, ShortBranches) >= 0 ||
LineMatchX (L, LongBranches) >= 0) { LineMatchX (L, LongBranches) >= 0) {
const char* Target = L->Line+5; const char* Target = L->Line+5;
if (Target[0] == 'L') { if (Target[0] == 'L') {
@@ -1169,12 +1190,12 @@ static unsigned RVUInt2 (Line* L,
U1 = RVUInt1 (L, LC, Used, Unused); U1 = RVUInt1 (L, LC, Used, Unused);
return U1 | U2; /* Used in any of the branches */ return U1 | U2; /* Used in any of the branches */
} }
} } else {
/* Search for the instruction in this line */ /* Search for the instruction in this line */
I = FindCmd (L); I = FindCmd (L);
/* If we don't find it, assume all other registers are */ /* If we don't find it, assume all other registers are used */
if (I < 0) { if (I < 0) {
break; break;
} }
@@ -1204,6 +1225,8 @@ static unsigned RVUInt2 (Line* L,
Unused |= R; Unused |= R;
} }
}
/* If we know about all registers, bail out */ /* If we know about all registers, bail out */
if ((Used | Unused) == REG_ALL) { if ((Used | Unused) == REG_ALL) {
break; break;

View File

@@ -166,7 +166,7 @@ static void doreturn (void)
/* Handle 'return' statement here */ /* Handle 'return' statement here */
{ {
struct expent lval; 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? */ int HaveVal = 0; /* Do we have a return value in ax? */
@@ -177,7 +177,7 @@ static void doreturn (void)
} }
if (evalexpr (CF_NONE, hie0, &lval) == 0) { if (evalexpr (CF_NONE, hie0, &lval) == 0) {
/* Constant value */ /* Constant value */
etype = CF_CONST; Flags = CF_CONST;
} else { } else {
/* Value in the primary register */ /* Value in the primary register */
HaveVal = 1; HaveVal = 1;
@@ -185,13 +185,13 @@ static void doreturn (void)
/* Convert the return value to the type of the function result */ /* Convert the return value to the type of the function result */
if (!HasVoidReturn (CurrentFunc)) { if (!HasVoidReturn (CurrentFunc)) {
etype |= assignadjust (GetReturnType (CurrentFunc), &lval) & ~CF_CONST; Flags |= (assignadjust (GetReturnType (CurrentFunc), &lval) & ~CF_CONST) | CF_REG;
} }
} else if (!HasVoidReturn (CurrentFunc)) { } else if (!HasVoidReturn (CurrentFunc)) {
Error ("Function `%s' must return a value", GetFuncName (CurrentFunc)); Error ("Function `%s' must return a value", GetFuncName (CurrentFunc));
} }
RestoreRegVars (HaveVal); RestoreRegVars (HaveVal);
g_leave (etype, lval.e_const); g_leave (Flags, lval.e_const);
} }