1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 04:30:10 +00:00

Do not save any register variables when entering main(). Do not restore the C

stack when leaving main(). Both are unnecessary and just bloat the executable.
This commit is contained in:
Kugel Fuhr 2024-09-01 12:41:25 +02:00
parent b688cfa0c0
commit b5cc68d6e2
4 changed files with 65 additions and 34 deletions

View File

@ -507,34 +507,39 @@ void g_enter (unsigned flags, unsigned argsize)
void g_leave (void) void g_leave (int IsMainFunc)
/* Function epilogue */ /* Function epilogue */
{ {
/* How many bytes of locals do we have to drop? */ /* In the main function nothing has to be dropped because the program
unsigned ToDrop = (unsigned) -StackPtr; ** is terminated anyway.
*/
if (!IsMainFunc) {
/* How many bytes of locals do we have to drop? */
unsigned ToDrop = (unsigned) -StackPtr;
/* If we didn't have a variable argument list, don't call leave */ /* If we didn't have a variable argument list, don't call leave */
if (funcargs >= 0) { if (funcargs >= 0) {
/* Drop stackframe if needed */ /* Drop stackframe if needed */
g_drop (ToDrop + funcargs); g_drop (ToDrop + funcargs);
} else if (StackPtr != 0) { } else if (StackPtr != 0) {
/* We've a stack frame to drop */
if (ToDrop > 255) {
g_drop (ToDrop); /* Inlines the code */
AddCodeLine ("jsr leave");
} else {
AddCodeLine ("ldy #$%02X", ToDrop);
AddCodeLine ("jsr leavey");
}
/* We've a stack frame to drop */
if (ToDrop > 255) {
g_drop (ToDrop); /* Inlines the code */
AddCodeLine ("jsr leave");
} else { } else {
AddCodeLine ("ldy #$%02X", ToDrop);
AddCodeLine ("jsr leavey"); /* Nothing to drop */
AddCodeLine ("jsr leave");
} }
} else {
/* Nothing to drop */
AddCodeLine ("jsr leave");
} }
/* Add the final rts */ /* Add the final rts */

View File

@ -247,7 +247,7 @@ void g_scale (unsigned flags, long val);
void g_enter (unsigned flags, unsigned argsize); void g_enter (unsigned flags, unsigned argsize);
/* Function prologue */ /* Function prologue */
void g_leave (void); void g_leave (int IsMainFunc);
/* Function epilogue */ /* Function epilogue */

View File

@ -646,11 +646,13 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
/* Output the function exit code label */ /* Output the function exit code label */
g_defcodelabel (F_GetRetLab (CurrentFunc)); g_defcodelabel (F_GetRetLab (CurrentFunc));
/* Restore the register variables */ /* Restore the register variables (not necessary for main function) */
F_RestoreRegVars (CurrentFunc); if (!F_IsMainFunc (CurrentFunc)) {
F_RestoreRegVars (CurrentFunc);
}
/* Generate the exit code */ /* Generate the exit code */
g_leave (); g_leave (F_IsMainFunc (CurrentFunc));
/* Emit references to imports/exports */ /* Emit references to imports/exports */
EmitExternals (); EmitExternals ();

View File

@ -111,22 +111,31 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg)
/* Get the size of the variable */ /* Get the size of the variable */
unsigned Size = SizeOf (Decl->Type); unsigned Size = SizeOf (Decl->Type);
/* Save the current contents of the register variable on stack */
F_AllocLocalSpace (CurrentFunc);
g_save_regvars (Reg, Size);
/* Add the symbol to the symbol table. We do that now, because for register
** variables the current stack pointer is implicitly used as location for
** the save area.
*/
Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg);
/* Check for an optional initialization */ /* Check for an optional initialization */
if (CurTok.Tok == TOK_ASSIGN) { if (CurTok.Tok == TOK_ASSIGN) {
/* Skip the '=' */ /* Skip the '=' */
NextToken (); NextToken ();
/* If the register variable is initialized, the initialization code may
** access other already declared variables. This means that we have to
** allocate them now.
*/
F_AllocLocalSpace (CurrentFunc);
/* Save the current contents of the register variable on stack. This is
** not necessary for the main function.
*/
if (!F_IsMainFunc (CurrentFunc)) {
g_save_regvars (Reg, Size);
}
/* Add the symbol to the symbol table. We do that now, because for
** register variables the current stack pointer is implicitly used
** as location for the save area (unused in case of main()).
*/
Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg);
/* Special handling for compound types */ /* Special handling for compound types */
if (IsCompound) { if (IsCompound) {
@ -173,6 +182,21 @@ static void ParseRegisterDecl (Declarator* Decl, int Reg)
/* Mark the variable as referenced */ /* Mark the variable as referenced */
Sym->Flags |= SC_REF; Sym->Flags |= SC_REF;
} else {
/* Save the current contents of the register variable on stack. This is
** not necessary for the main function.
*/
if (!F_IsMainFunc (CurrentFunc)) {
F_AllocLocalSpace (CurrentFunc);
g_save_regvars (Reg, Size);
}
/* Add the symbol to the symbol table. We do that now, because for
** register variables the current stack pointer is implicitly used
** as location for the save area (unused in case of main()).
*/
Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg);
} }
/* Cannot allocate a variable of unknown size */ /* Cannot allocate a variable of unknown size */