1
0
mirror of https://github.com/cc65/cc65.git synced 2025-08-09 13:25:06 +00:00

Allow initialization of local variables of compound type

git-svn-id: svn://svn.cc65.org/cc65/trunk@1458 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2002-10-10 21:15:24 +00:00
parent dcdaf8fd49
commit 83fb2c8ab4
3 changed files with 168 additions and 48 deletions

View File

@@ -3913,6 +3913,65 @@ void g_zerobytes (unsigned n)
void g_initauto (unsigned Label, unsigned Size)
/* Initialize a local variable at stack offset zero from static data */
{
unsigned CodeLabel = GetLocalLabel ();
CheckLocalOffs (Size);
if (Size <= 128) {
ldyconst (Size-1);
g_defcodelabel (CodeLabel);
AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0));
AddCodeLine ("sta (sp),y");
AddCodeLine ("dey");
AddCodeLine ("bpl %s", LocalLabelName (CodeLabel));
} else if (Size <= 256) {
ldyconst (0);
g_defcodelabel (CodeLabel);
AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, Label, 0));
AddCodeLine ("sta (sp),y");
AddCodeLine ("iny");
AddCodeLine ("cpy #$%02X", (unsigned char) Size);
AddCodeLine ("bne %s", LocalLabelName (CodeLabel));
}
}
void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size)
/* Initialize a static local variable from static initialization data */
{
if (Size <= 128) {
unsigned CodeLabel = GetLocalLabel ();
ldyconst (Size-1);
g_defcodelabel (CodeLabel);
AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, InitLabel, 0));
AddCodeLine ("sta %s,y", GetLabelName (CF_STATIC, VarLabel, 0));
AddCodeLine ("dey");
AddCodeLine ("bpl %s", LocalLabelName (CodeLabel));
} else if (Size <= 256) {
unsigned CodeLabel = GetLocalLabel ();
ldyconst (0);
g_defcodelabel (CodeLabel);
AddCodeLine ("lda %s,y", GetLabelName (CF_STATIC, InitLabel, 0));
AddCodeLine ("sta %s,y", GetLabelName (CF_STATIC, VarLabel, 0));
AddCodeLine ("iny");
AddCodeLine ("cpy #$%02X", (unsigned char) Size);
AddCodeLine ("bne %s", LocalLabelName (CodeLabel));
} else {
/* Use the easy way here: memcpy */
g_getimmed (CF_STATIC, VarLabel, 0);
AddCodeLine ("jsr pushax");
g_getimmed (CF_STATIC, InitLabel, 0);
AddCodeLine ("jsr pushax");
g_getimmed (CF_INT | CF_UNSIGNED | CF_CONST, Size, 0);
AddCodeLine ("jsr %s", GetLabelName (CF_EXTERNAL, (unsigned long) "memcpy", 0));
}
}
/*****************************************************************************/
/* Switch statement */
/*****************************************************************************/

View File

@@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2001 Ullrich von Bassewitz */
/* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@cc65.org */
@@ -429,6 +429,12 @@ void g_defbytes (const void* bytes, unsigned count);
void g_zerobytes (unsigned n);
/* Output n bytes of data initialized with zero */
void g_initauto (unsigned Label, unsigned Size);
/* Initialize a local variable at stack offset zero from static data */
void g_initstatic (unsigned InitLabel, unsigned VarLabel, unsigned Size);
/* Initialize a static local variable from static initialization data */
/*****************************************************************************/

View File

@@ -141,6 +141,10 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned Size, unsigned* SC)
{
unsigned Flags;
unsigned SymData;
unsigned InitLabel;
/* Determine if this is a compound variable */
int IsCompound = IsClassStruct (Decl->Type) || IsTypeArray (Decl->Type);
/* Check if this is a variable on the stack or in static memory */
if (StaticLocals == 0) {
@@ -151,12 +155,40 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned Size, unsigned* SC)
ExprDesc lval;
/* Allocate previously reserved local space */
F_AllocLocalSpace (CurrentFunc);
/* Skip the '=' */
NextToken ();
/* Special handling for compound types */
if (IsCompound) {
/* First reserve space for the variable */
SymData = F_ReserveLocalSpace (CurrentFunc, Size);
/* Next, allocate the space on the stack. This means that the
* variable is now located at offset 0 from the current sp.
*/
F_AllocLocalSpace (CurrentFunc);
/* Switch to read only data */
g_userodata ();
/* Define a label for the initialization data */
InitLabel = GetLocalLabel ();
g_defdatalabel (InitLabel);
/* Parse the initialization generating a memory image of the
* data in the RODATA segment.
*/
ParseInit (Decl->Type);
/* Generate code to copy this data into the variable space */
g_initauto (InitLabel, Size);
} else {
/* Allocate previously reserved local space */
F_AllocLocalSpace (CurrentFunc);
/* Setup the type flags for the assignment */
Flags = (Size == 1)? CF_FORCECHAR : CF_NONE;
@@ -173,6 +205,8 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned Size, unsigned* SC)
/* Push the value */
g_push (Flags | TypeOf (Decl->Type), lval.ConstVal);
}
/* Mark the variable as referenced */
*SC |= SC_REF;
@@ -209,6 +243,25 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned Size, unsigned* SC)
/* Skip the '=' */
NextToken ();
if (IsCompound) {
/* Switch to read only data */
g_userodata ();
/* Define a label for the initialization data */
InitLabel = GetLocalLabel ();
g_defdatalabel (InitLabel);
/* Parse the initialization generating a memory image of the
* data in the RODATA segment.
*/
ParseInit (Decl->Type);
/* Generate code to copy this data into the variable space */
g_initstatic (InitLabel, SymData, Size);
} else {
/* Setup the type flags for the assignment */
Flags = (Size == 1)? CF_FORCECHAR : CF_NONE;
@@ -227,6 +280,8 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned Size, unsigned* SC)
/* Store the value into the variable */
g_putstatic (Flags | TypeOf (Decl->Type), SymData, 0);
}
/* Mark the variable as referenced */
*SC |= SC_REF;
}