{
/* How many bytes of locals do we have to drop? */
int k = -oursp;
-
+
/* If we didn't have a variable argument list, don't call leave */
if (funcargs >= 0) {
break;
case CF_LONG:
- /* Split the value into 4 bytes */
- B1 = (unsigned char) (Val >> 0);
- B2 = (unsigned char) (Val >> 8);
- B3 = (unsigned char) (Val >> 16);
- B4 = (unsigned char) (Val >> 24);
-
- /* Remember which bytes are done */
- Done = 0;
-
- /* Load the value */
- AddCodeLine ("ldx #$%02X", B2);
- Done |= 0x02;
- if (B2 == B3) {
- AddCodeLine ("stx sreg");
- Done |= 0x04;
- }
- if (B2 == B4) {
- AddCodeLine ("stx sreg+1");
- Done |= 0x08;
+ /* Split the value into 4 bytes */
+ B1 = (unsigned char) (Val >> 0);
+ B2 = (unsigned char) (Val >> 8);
+ B3 = (unsigned char) (Val >> 16);
+ B4 = (unsigned char) (Val >> 24);
+
+ /* Remember which bytes are done */
+ Done = 0;
+
+ /* Load the value */
+ AddCodeLine ("ldx #$%02X", B2);
+ Done |= 0x02;
+ if (B2 == B3) {
+ AddCodeLine ("stx sreg");
+ Done |= 0x04;
+ }
+ if (B2 == B4) {
+ AddCodeLine ("stx sreg+1");
+ Done |= 0x08;
}
if ((Done & 0x04) == 0 && B1 != B3) {
AddCodeLine ("lda #$%02X", B3);
+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 */
/*****************************************************************************/
/* */
/* */
/* */
-/* (C) 1998-2001 Ullrich von Bassewitz */
+/* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@cc65.org */
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 */
+
/*****************************************************************************/
{
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) {
ExprDesc lval;
- /* Allocate previously reserved local space */
- F_AllocLocalSpace (CurrentFunc);
-
/* Skip the '=' */
NextToken ();
- /* Setup the type flags for the assignment */
- Flags = (Size == 1)? CF_FORCECHAR : CF_NONE;
+ /* 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);
- /* Get the expression into the primary */
- if (evalexpr (Flags, hie1, &lval) == 0) {
- /* Constant expression. Adjust the types */
- assignadjust (Decl->Type, &lval);
- Flags |= CF_CONST;
} else {
- /* Expression is not constant and in the primary */
- assignadjust (Decl->Type, &lval);
- }
- /* Push the value */
- g_push (Flags | TypeOf (Decl->Type), lval.ConstVal);
+ /* Allocate previously reserved local space */
+ F_AllocLocalSpace (CurrentFunc);
+
+ /* Setup the type flags for the assignment */
+ Flags = (Size == 1)? CF_FORCECHAR : CF_NONE;
+
+ /* Get the expression into the primary */
+ if (evalexpr (Flags, hie1, &lval) == 0) {
+ /* Constant expression. Adjust the types */
+ assignadjust (Decl->Type, &lval);
+ Flags |= CF_CONST;
+ } else {
+ /* Expression is not constant and in the primary */
+ assignadjust (Decl->Type, &lval);
+ }
+
+ /* Push the value */
+ g_push (Flags | TypeOf (Decl->Type), lval.ConstVal);
+
+ }
/* Mark the variable as referenced */
*SC |= SC_REF;
/* Skip the '=' */
NextToken ();
- /* Setup the type flags for the assignment */
- Flags = (Size == 1)? CF_FORCECHAR : CF_NONE;
+ 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);
- /* Get the expression into the primary */
- if (evalexpr (Flags, hie1, &lval) == 0) {
- /* Constant expression. Adjust the types */
- assignadjust (Decl->Type, &lval);
- Flags |= CF_CONST;
- /* Load it into the primary */
- exprhs (Flags, 0, &lval);
} else {
- /* Expression is not constant and in the primary */
- assignadjust (Decl->Type, &lval);
- }
- /* Store the value into the variable */
- g_putstatic (Flags | TypeOf (Decl->Type), SymData, 0);
+ /* Setup the type flags for the assignment */
+ Flags = (Size == 1)? CF_FORCECHAR : CF_NONE;
+
+ /* Get the expression into the primary */
+ if (evalexpr (Flags, hie1, &lval) == 0) {
+ /* Constant expression. Adjust the types */
+ assignadjust (Decl->Type, &lval);
+ Flags |= CF_CONST;
+ /* Load it into the primary */
+ exprhs (Flags, 0, &lval);
+ } else {
+ /* Expression is not constant and in the primary */
+ assignadjust (Decl->Type, &lval);
+ }
+
+ /* Store the value into the variable */
+ g_putstatic (Flags | TypeOf (Decl->Type), SymData, 0);
+
+ }
/* Mark the variable as referenced */
*SC |= SC_REF;