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:
parent
b688cfa0c0
commit
b5cc68d6e2
@ -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 */
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 ();
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user