]> git.sur5r.net Git - cc65/commitdiff
Reenable register variables
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 24 Nov 2002 23:31:54 +0000 (23:31 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 24 Nov 2002 23:31:54 +0000 (23:31 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1625 b7a2c559-68d2-44c3-8de9-860c34a00d81

15 files changed:
src/cc65/asmcode.c
src/cc65/codegen.c
src/cc65/codegen.h
src/cc65/codeopt.c
src/cc65/compile.c
src/cc65/coptadd.c
src/cc65/coptadd.h
src/cc65/datatype.h
src/cc65/declare.c
src/cc65/expr.c
src/cc65/locals.c
src/cc65/main.c
src/cc65/symentry.c
src/cc65/symentry.h
src/cc65/symtab.c

index 39092092fc4990cd60ba065dbe7f63302a1e4178..788dd5bece3f9fd0d7c0f339baa6d1d65ab5478a 100644 (file)
@@ -72,7 +72,7 @@ void MoveCode (CodeMark Start, CodeMark End, CodeMark Target)
 /* Move the code between Start (inclusive) and End (exclusive) to
  * (before) Target.
  */
-{                                      
+{
     CS_MoveEntries (CS->Code, Start, End - Start, Target);
 }
 
@@ -93,7 +93,7 @@ void WriteOutput (FILE* F)
     Entry  = SymTab->SymHead;
     while (Entry) {
                if (IsTypeFunc (Entry->Type)            &&
-                   (Entry->Flags & SC_DEF) != 0        &&
+                   SymIsDef (Entry)                    &&
                    (Entry->Flags & (SC_REF | SC_EXTERN)) != 0) {
                    /* Function which is defined and referenced or extern */
                    CS_MergeLabels (Entry->V.F.Seg->Code);
index c4a50b139551d301bad60b8ce223ead0a9cab8d7..6e05351d0d22d1d335214ae46b601f774f0fde6c 100644 (file)
@@ -134,7 +134,7 @@ static const char* GetLabelName (unsigned Flags, unsigned long Label, long Offs)
        default:
            Internal ("Invalid address flags");
     }
-
+                   
     /* Return a pointer to the static buffer */
     return Buf;
 }
@@ -3981,6 +3981,21 @@ void g_zerobytes (unsigned n)
 
 
 
+void g_initregister (unsigned Label, unsigned Reg, unsigned Size)
+/* Initialize a register variable from static initialization data */
+{
+    /* Register variables do always have less than 128 bytes */
+    unsigned CodeLabel = GetLocalLabel ();
+    ldxconst (Size-1);
+    g_defcodelabel (CodeLabel);
+    AddCodeLine ("lda %s,x", GetLabelName (CF_STATIC, Label, 0));
+    AddCodeLine ("sta %s,x", GetLabelName (CF_REGVAR, Reg, 0));
+    AddCodeLine ("dex");
+    AddCodeLine ("bpl %s", LocalLabelName (CodeLabel));
+}
+
+
+
 void g_initauto (unsigned Label, unsigned Size)
 /* Initialize a local variable at stack offset zero from static data */
 {
index 68e15b1897c0baebe83650c31affa0f901b56cb2..649d5e789af278121a5a8301b6a4ac3a03028c05 100644 (file)
@@ -432,6 +432,9 @@ void g_defbytes (const void* bytes, unsigned count);
 void g_zerobytes (unsigned n);
 /* Output n bytes of data initialized with zero */
 
+void g_initregister (unsigned Label, unsigned Reg, unsigned Size);
+/* Initialize a register variable from static initialization data */
+
 void g_initauto (unsigned Label, unsigned Size);
 /* Initialize a local variable at stack offset zero from static data */
 
index b58acc6f93f146f3eff0428857194b73d82779a3..88672fc1c15aa6de04bd0c21d3cac6c8502d4f1d 100644 (file)
@@ -1391,7 +1391,8 @@ static OptFunc DOpt65C02Ind       = { Opt65C02Ind,     "Opt65C02Ind",     100, 0,
 static OptFunc DOpt65C02Stores  = { Opt65C02Stores,  "Opt65C02Stores",  100, 0, 0, 0, 0, 0 };
 static OptFunc DOptAdd1                = { OptAdd1,         "OptAdd1",         125, 0, 0, 0, 0, 0 };
 static OptFunc DOptAdd2                = { OptAdd2,         "OptAdd2",         200, 0, 0, 0, 0, 0 };
-static OptFunc DOptAdd3                = { OptAdd3,         "OptAdd3",          40, 0, 0, 0, 0, 0 };
+static OptFunc DOptAdd3                = { OptAdd3,         "OptAdd3",          90, 0, 0, 0, 0, 0 };
+static OptFunc DOptAdd4                = { OptAdd4,         "OptAdd4",          40, 0, 0, 0, 0, 0 };
 static OptFunc DOptBoolTrans    = { OptBoolTrans,    "OptBoolTrans",    100, 0, 0, 0, 0, 0 };
 static OptFunc DOptBranchDist          = { OptBranchDist,   "OptBranchDist",     0, 0, 0, 0, 0, 0 };
 static OptFunc DOptCmp1                = { OptCmp1,         "OptCmp1",          85, 0, 0, 0, 0, 0 };
@@ -1454,6 +1455,7 @@ static OptFunc* OptFuncs[] = {
     &DOptAdd1,
     &DOptAdd2,
     &DOptAdd3,
+    &DOptAdd4,
     &DOptBoolTrans,
     &DOptBranchDist,
     &DOptCmp1,
@@ -1752,6 +1754,7 @@ static unsigned RunOptGroup1 (CodeSeg* S)
     Changes += RunOptFunc (S, &DOptNegAX4, 1);
     Changes += RunOptFunc (S, &DOptAdd1, 1);
     Changes += RunOptFunc (S, &DOptAdd2, 1);
+    Changes += RunOptFunc (S, &DOptAdd3, 1);
     Changes += RunOptFunc (S, &DOptShift1, 1);
     Changes += RunOptFunc (S, &DOptShift2, 1);
     Changes += RunOptFunc (S, &DOptShift3, 1);
index 0e751edf9701bf0db4dbffc4a57b0ed4575896b7..f194cb1aa023d3fe5a9642f0a65a0be905159580 100644 (file)
@@ -231,16 +231,16 @@ static void Parse (void)
 
            /* Function */
            if (!comma) {
-
                if (CurTok.Tok == TOK_SEMI) {
-
                    /* Prototype only */
                    NextToken ();
-
-               } else {
-                   if (Entry) {
-                       NewFunc (Entry);
-                   }
+               } else if (Entry) {
+                    /* Function body definition */
+                    if (SymIsDef (Entry)) {
+                        Error ("Body for function `%s' has already been defined",
+                               Entry->Name);
+                    }
+                    NewFunc (Entry);
                }
            }
 
index 3fa886fed7b3acaa743cd49ee903249991efdcc3..3a11a9c6a71abdfe88fe996fb1ed876188a310f5 100644 (file)
@@ -284,6 +284,95 @@ unsigned OptAdd2 (CodeSeg* S)
 
 
 unsigned OptAdd3 (CodeSeg* S)
+/* Search for the sequence
+ *
+ *     jsr     pushax
+ *      lda     xxx
+ *     ldy     yyy
+ *      jsr     tosaddax
+ *
+ * and replace it by
+ *
+ *      clc
+ *      adc     xxx
+ *      pha
+ *      txa
+ *      adc     yyy
+ *      tax
+ *      pla
+ */
+{
+    unsigned Changes = 0;
+
+    /* Walk over the entries */
+    unsigned I = 0;
+    while (I < CS_GetEntryCount (S)) {
+
+       CodeEntry* L[4];
+
+       /* Get next entry */
+               L[0] = CS_GetEntry (S, I);
+
+       /* Check for the sequence */
+        if (CE_IsCallTo (L[0], "pushax")                        &&
+                   CS_GetEntries (S, L+1, I+1, 3)                      &&
+            !CS_RangeHasLabel (S, I+1, 3)                       &&
+            L[1]->OPC == OP65_LDA                               &&
+            (L[1]->AM == AM65_ABS || L[1]->AM == AM65_ZP)       &&
+            L[2]->OPC == OP65_LDX                               &&
+            (L[2]->AM == AM65_ABS || L[2]->AM == AM65_ZP)       &&
+            CE_IsCallTo (L[3], "tosaddax")) {
+
+            CodeEntry* X;
+
+            /* Insert new code behind the sequence */
+           X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+4);
+
+            /* adc xxx */
+           X = NewCodeEntry (OP65_ADC, L[1]->AM, L[1]->Arg, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+5);
+
+            /* pha */
+           X = NewCodeEntry (OP65_PHA, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+6);
+
+            /* txa */
+           X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+7);
+
+            /* adc yyy */
+           X = NewCodeEntry (OP65_ADC, L[2]->AM, L[2]->Arg, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+8);
+
+            /* tax */
+           X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+9);
+
+            /* pla */
+           X = NewCodeEntry (OP65_PLA, AM65_IMP, 0, 0, L[3]->LI);
+           CS_InsertEntry (S, X, I+10);
+
+           /* Delete the old code */
+           CS_DelEntries (S, I, 4);
+
+           /* Remember, we had changes */
+           ++Changes;
+
+       }
+
+       /* Next entry */
+       ++I;
+
+    }
+
+    /* Return the number of changes made */
+    return Changes;
+}
+
+
+
+unsigned OptAdd4 (CodeSeg* S)
 /* Search for the sequence
  *
  *     adc     ...
@@ -306,7 +395,7 @@ unsigned OptAdd3 (CodeSeg* S)
                CodeEntry* E = CS_GetEntry (S, I);
 
        /* Check for the sequence */
-               if (E->OPC == OP65_ADC                               &&
+               if (E->OPC == OP65_ADC                               &&
            CS_GetEntries (S, L, I+1, 3)                     &&
                    (L[0]->OPC == OP65_BCC || L[0]->OPC == OP65_JCC) &&
            L[0]->JumpTo != 0                                &&
@@ -335,4 +424,3 @@ unsigned OptAdd3 (CodeSeg* S)
 
 
 
-
index 545552bcd2fe70143874fee7b16520cf3a9ea51a..accf3d831d23a224cd8c02ac08c80bb6be8c0c5a 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001      Ullrich von Bassewitz                                       */
+/* (C) 2001-2002 Ullrich von Bassewitz                                       */
 /*               Wacholderweg 14                                             */
 /*               D-70597 Stuttgart                                           */
 /* EMail:        uz@cc65.org                                                 */
@@ -97,6 +97,25 @@ unsigned OptAdd2 (CodeSeg* S);
  */
 
 unsigned OptAdd3 (CodeSeg* S);
+/* Search for the sequence
+ *
+ *     jsr     pushax
+ *      lda     xxx
+ *     ldy     yyy
+ *      jsr     tosaddax
+ *
+ * and replace it by
+ *
+ *      clc
+ *      adc     xxx
+ *      pha
+ *      txa
+ *      adc     yyy
+ *      tax
+ *      pla
+ */                           
+
+unsigned OptAdd4 (CodeSeg* S);
 /* Search for the sequence
  *
  *     adc     ...
index 75892f0f11e6f210d48c7922cd6171691c0235da..94ae9ec4a9f6977d7eab4a6be99c6f11fc1e37a6 100644 (file)
@@ -42,6 +42,7 @@
 
 /* common */
 #include "attrib.h"
+#include "inline.h"
 
 /* cc65 */
 #include "funcdesc.h"
index e2770e1ca0e9f39429cc46082a5403d1f3618923..0c647c83574a454291a351b02dd50770575ece91 100644 (file)
@@ -297,8 +297,11 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
            Declaration Decl;
            ParseDecl (&Spec, &Decl, 0);
 
+            /* Get the offset of this field */
+            Offs = (StructType == T_STRUCT)? Size : 0;
+
            /* Add a field entry to the table */
-           AddLocalSym (Decl.Ident, Decl.Type, SC_SFLD, (StructType == T_STRUCT)? Size : 0);
+           AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, Offs);
 
            /* Calculate offset of next field/size of the union */
            Offs = CheckedSizeOf (Decl.Type);
@@ -516,7 +519,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
 
         case TOK_IDENT:
            Entry = FindSym (CurTok.Ident);
-           if (Entry && IsTypeDef (Entry)) {
+           if (Entry && SymIsTypeDef (Entry)) {
                        /* It's a typedef */
                NextToken ();
                TypeCpy (D->Type, Entry->Type);
@@ -746,7 +749,7 @@ static FuncDesc* ParseFuncDecl (const DeclSpec* Spec)
         * if it's some other identifier, it's an old style parameter list.
         */
        Sym = FindSym (CurTok.Ident);
-       if (Sym == 0 || !IsTypeDef (Sym)) {
+       if (Sym == 0 || !SymIsTypeDef (Sym)) {
            /* Old style (K&R) function. Assume variable param list. */
            F->Flags |= (FD_OLDSTYLE | FD_VARIADIC);
 
index aacc96891ddcee57e7e1ce687222e4bbdd450fb1..afdcf42a78fa2da878923b8bb8de5adffe518763 100644 (file)
@@ -183,7 +183,7 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush)
     }
     flags = g_typeadjust (ltype, rtype);
 
-    /* Set the type of the result */
+    /* Set the type of the result */            
     lhs->Type = promoteint (lhst, rhst);
 
     /* Return the code generator flags */
@@ -437,7 +437,7 @@ static int istypeexpr (void)
           (NextTok.Tok == TOK_CONST)                                    ||
                   (NextTok.Tok  == TOK_IDENT                                    &&
           (Entry = FindSym (NextTok.Ident)) != 0                        &&
-          IsTypeDef (Entry)));
+          SymIsTypeDef (Entry)));
 }
 
 
@@ -941,7 +941,7 @@ static int primary (ExprDesc* lval)
            } else if ((Sym->Flags & SC_REGISTER) == SC_REGISTER) {
                /* Register variable, zero page based */
                lval->Flags = E_MGLOBAL | E_MCONST | E_TREGISTER;
-               lval->Name  = Sym->V.Offs;
+               lval->Name  = Sym->V.R.RegOffs;
                lval->ConstVal = 0;
            } else if ((Sym->Flags & SC_STATIC) == SC_STATIC) {
                /* Static variable */
index fcadb4e9a3f08b416425df28661207c60fb7c23b..ad87c3ebd75006b1ee87ffa7fdbc37e7e251533a 100644 (file)
@@ -101,28 +101,25 @@ void DoneRegVars (void)
 
 
 
-static int AllocRegVar (const SymEntry* Sym, const type* tarray)
-/* Allocate a register variable with the given amount of storage. If the
- * allocation was successful, return the offset of the register variable in
- * the register bank (zero page storage). If there is no register space left,
- * return -1.
+static int AllocRegVar (const type* Type)
+/* Allocate a register variable for the given variable type. If the allocation
+ * was successful, return the offset of the register variable in the register
+ * bank (zero page storage). If there is no register space left, return -1.
  */
 {
     /* Maybe register variables are disabled... */
     if (EnableRegVars) {
 
        /* Get the size of the variable */
-       unsigned Size = CheckedSizeOf (tarray);
+       unsigned Size = CheckedSizeOf (Type);
 
        /* Do we have space left? */
        if (RegOffs >= Size) {
-
            /* Space left. We allocate the variables from high to low addresses,
             * so the adressing is compatible with the saved values on stack.
             * This allows shorter code when saving/restoring the variables.
             */
            RegOffs -= Size;
-           RegSyms [RegSymCount++] = Sym;
            return RegOffs;
        }
     }
@@ -133,6 +130,96 @@ static int AllocRegVar (const SymEntry* Sym, const type* tarray)
 
 
 
+static void RememberRegVar (const SymEntry* Sym)
+/* Remember the given register variable */
+{
+    RegSyms[RegSymCount++] = Sym;
+}
+
+
+
+static unsigned ParseRegisterDecl (Declaration* Decl, unsigned* SC, int Reg)
+/* Parse the declaration of a register variable. The function returns the
+ * symbol data, which is the offset of the variable in the register bank.
+ */
+{
+    unsigned Flags;
+    unsigned InitLabel;
+
+    /* Determine if this is a compound variable */
+    int IsCompound = IsClassStruct (Decl->Type) || IsTypeArray (Decl->Type);
+
+    /* Get the size of the variable */
+    unsigned Size = SizeOf (Decl->Type);
+
+    /* Save the current contents of the register variable on stack */
+    F_AllocLocalSpace (CurrentFunc);
+    g_save_regvars (Reg, Size);
+
+    /* Check for an optional initialization */
+    if (CurTok.Tok == TOK_ASSIGN) {
+
+        ExprDesc lval;
+
+        /* Skip the '=' */
+        NextToken ();
+
+        /* Special handling for compound types */
+        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_initregister (InitLabel, Reg, Size);
+
+        } else {
+
+            /* Setup the type flags for the assignment */
+            Flags = CF_REGVAR;
+            if (Size == SIZEOF_CHAR) {
+                Flags |= CF_FORCECHAR;
+            }
+
+            /* 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);
+            }
+
+            /* Store the value into the variable */
+            g_putstatic (Flags | TypeOf (Decl->Type), Reg, 0);
+
+        }
+
+        /* Mark the variable as referenced */
+        *SC |= SC_REF;
+    }
+
+    /* Cannot allocate a variable of zero size */
+    if (Size == 0) {
+        Error ("Variable `%s' has unknown size", Decl->Ident);
+    }
+
+    /* Return the symbol data */
+    return Reg;
+}
+
+
+
 static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
 /* Parse the declaration of an auto variable. The function returns the symbol
  * data, which is the offset for variables on the stack, and the label for
@@ -152,8 +239,7 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
     /* Check if this is a variable on the stack or in static memory */
     if (StaticLocals == 0) {
 
-        /* Change SC in case it was register */
-        *SC = (*SC & ~SC_REGISTER) | SC_AUTO;
+        /* Check for an optional initialization */
         if (CurTok.Tok == TOK_ASSIGN) {
 
             ExprDesc lval;
@@ -226,7 +312,7 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
     } else {
 
         /* Static local variables. */
-        *SC = (*SC & ~(SC_REGISTER | SC_AUTO)) | SC_STATIC;
+        *SC = (*SC & ~SC_AUTO) | SC_STATIC;
 
         /* Put them into the BSS */
         g_usebss ();
@@ -369,7 +455,9 @@ static void ParseOneDecl (const DeclSpec* Spec)
 {
     unsigned    SC;            /* Storage class for symbol */
     unsigned    SymData = 0;    /* Symbol data (offset, label name, ...) */
-    Declaration Decl;          /* Declaration data structure */
+    Declaration Decl;          /* Declaration data structure */
+    SymEntry*   Sym;            /* Symbol declared */
+
 
     /* Remember the storage class for the new symbol */
     SC = Spec->StorageClass;
@@ -391,33 +479,48 @@ static void ParseOneDecl (const DeclSpec* Spec)
      * To avoid problems later, use an anonymous name here.
      */
     if (Decl.Ident[0] == '\0') {
-       AnonName (Decl.Ident, "param");
+               AnonName (Decl.Ident, "param");
     }
 
     /* Handle anything that needs storage (no functions, no typdefs) */
     if ((SC & SC_FUNC) != SC_FUNC && (SC & SC_TYPEDEF) != SC_TYPEDEF) {
 
-        /* */
-               if (SC & (SC_AUTO | SC_REGISTER)) {
+        /* If we have a register variable, try to allocate a register and
+         * convert the declaration to "auto" if this is not possible.
+         */
+        int Reg = 0;    /* Initialize to avoid gcc complains */
+        if ((SC & SC_REGISTER) != 0 && (Reg = AllocRegVar (Decl.Type)) < 0) {
+            /* No space for this register variable, convert to auto */
+            SC = (SC & ~SC_REGISTER) | SC_AUTO;
+        }
 
+        /* Check the variable type */
+        if (SC & SC_REGISTER) {
+            /* Register variable */
+            SymData = ParseRegisterDecl (&Decl, &SC, Reg);
+               } else if (SC & SC_AUTO) {
             /* Auto variable */
             SymData = ParseAutoDecl (&Decl, &SC);
-
-       } else if ((SC & SC_STATIC) == SC_STATIC) {
-
+               } else if (SC & SC_STATIC) {
             /* Static variable */
             SymData = ParseStaticDecl (&Decl, &SC);
-
-               }
+               } else {
+            Internal ("Invalid storage class in ParseOneDecl: %04X", SC);
+        }
     }
 
-    /* If the symbol is not marked as external, it will be defined */
+    /* If the symbol is not marked as external, it will be defined now */
     if ((SC & SC_EXTERN) == 0) {
-       SC |= SC_DEF;
+               SC |= SC_DEF;
     }
 
     /* Add the symbol to the symbol table */
-    AddLocalSym (Decl.Ident, Decl.Type, SC, SymData);
+    Sym = AddLocalSym (Decl.Ident, Decl.Type, SC, SymData);
+
+    /* If we had declared a register variable, remember it now */
+    if (SC & SC_REGISTER) {
+        RememberRegVar (Sym);
+    }
 }
 
 
@@ -510,8 +613,8 @@ void RestoreRegVars (int HaveResult)
     while (I < RegSymCount) {
 
        /* Check for more than one variable */
-               const SymEntry* Sym = RegSyms[I];
-       Offs  = Sym->V.Offs;
+               const SymEntry* Sym = RegSyms[I];    
+       Offs  = Sym->V.R.SaveOffs;
        Bytes = CheckedSizeOf (Sym->Type);
        J = I+1;
 
@@ -524,7 +627,7 @@ void RestoreRegVars (int HaveResult)
            int Size = CheckedSizeOf (NextSym->Type);
 
            /* Adjacent variable? */
-           if (NextSym->V.Offs + Size != Offs) {
+           if (NextSym->V.R.SaveOffs + Size != Offs) {
                /* No */
                break;
            }
@@ -537,7 +640,7 @@ void RestoreRegVars (int HaveResult)
        }
 
        /* Restore the memory range */
-               g_restore_regvars (Offs, Sym->V.Offs, Bytes);
+               g_restore_regvars (Offs, Sym->V.R.RegOffs, Bytes);
 
        /* Next round */
        I = J;
index da92fcd727432351eb75e2d5cf34e9150b2e2696..c79f52acf325d09102b4c7b28e0712dd99032f45 100644 (file)
@@ -91,6 +91,7 @@ static void Usage (void)
                     "  -h\t\t\tHelp (this text)\n"
                     "  -j\t\t\tDefault characters are signed\n"
                     "  -o name\t\tName the output file\n"
+             "  -r\t\t\tEnable register variables\n"
                     "  -t sys\t\tSet the target system\n"
                     "  -v\t\t\tIncrease verbosity\n"
             "\n"
@@ -112,6 +113,7 @@ static void Usage (void)
             "  --help\t\tHelp (this text)\n"
                     "  --include-dir dir\tSet an include directory search path\n"
             "  --list-opt-steps\tList all optimizer steps and exit\n"
+             "  --register-vars\tEnable register variables\n"
                     "  --rodata-name seg\tSet the name of the RODATA segment\n"
                     "  --signed-chars\tDefault characters are signed\n"
                     "  --static-locals\tMake local variables static\n"
@@ -528,6 +530,15 @@ static void OptListOptSteps (const char* Opt attribute ((unused)),
 
 
 
+static void OptRegisterVars (const char* Opt attribute ((unused)), 
+                             const char* Arg attribute ((unused)))
+/* Handle the --register-vars option */
+{
+    EnableRegVars = 1;
+}
+
+
+
 static void OptRodataName (const char* Opt attribute ((unused)), const char* Arg)
 /* Handle the --rodata-name option */
 {
@@ -607,10 +618,11 @@ int main (int argc, char* argv[])
        { "--help",             0,      OptHelp                 },
        { "--include-dir",      1,      OptIncludeDir           },
        { "--list-opt-steps",   0,      OptListOptSteps         },
+        { "--register-vars",    0,      OptRegisterVars         },
        { "--rodata-name",      1,      OptRodataName           },
        { "--signed-chars",     0,      OptSignedChars          },
                { "--static-locals",    0,      OptStaticLocals         },
-       { "--target",           1,      OptTarget               },
+       { "--target",           1,      OptTarget               },
        { "--verbose",          0,      OptVerbose              },
        { "--version",          0,      OptVersion              },
     };
@@ -666,6 +678,10 @@ int main (int argc, char* argv[])
                    OutputFile = GetArg (&I, 2);
                    break;
 
+                case 'r':
+                    OptRegisterVars (Arg, 0);
+                    break;
+
                case 't':
                    OptTarget (Arg, GetArg (&I, 2));
                    break;
@@ -690,8 +706,8 @@ int main (int argc, char* argv[])
                                OptStaticLocals (Arg, 0);
                                break;
                            default:
-                               UnknownOption (Arg);
-                               break;
+                               UnknownOption (Arg);
+                               break;
                        }
                    }
                    break;
index 8882cdb627fbdf1ad225966eaf4c8f20277186fb..6745680d3820278bfa53931cd26a3dbabdaa3f09 100644 (file)
@@ -94,22 +94,22 @@ void DumpSymEntry (FILE* F, const SymEntry* E)
        unsigned            Val;
     } Flags [] = {
        /* Beware: Order is important! */
-       { "SC_TYPEDEF",     SC_TYPEDEF  },
-       { "SC_SFLD",        SC_SFLD     },
-       { "SC_STRUCT",      SC_STRUCT   },
-       { "SC_AUTO",        SC_AUTO     },
-       { "SC_REGISTER",    SC_REGISTER },
-       { "SC_STATIC",      SC_STATIC   },
-       { "SC_EXTERN",      SC_EXTERN   },
-       { "SC_ENUM",        SC_ENUM     },
-       { "SC_CONST",       SC_CONST    },
-       { "SC_LABEL",       SC_LABEL    },
-       { "SC_PARAM",       SC_PARAM    },
-       { "SC_FUNC",        SC_FUNC     },
-       { "SC_STORAGE",     SC_STORAGE  },
-       { "SC_DEF",         SC_DEF      },
-       { "SC_REF",         SC_REF      },
-       { "SC_ZEROPAGE",    SC_ZEROPAGE },
+       { "SC_TYPEDEF",     SC_TYPEDEF          },
+               { "SC_STRUCTFIELD", SC_STRUCTFIELD      },
+       { "SC_STRUCT",      SC_STRUCT           },
+       { "SC_AUTO",        SC_AUTO             },
+       { "SC_REGISTER",    SC_REGISTER         },
+       { "SC_STATIC",      SC_STATIC           },
+       { "SC_EXTERN",      SC_EXTERN           },
+       { "SC_ENUM",        SC_ENUM             },
+       { "SC_CONST",       SC_CONST            },
+       { "SC_LABEL",       SC_LABEL            },
+       { "SC_PARAM",       SC_PARAM            },
+       { "SC_FUNC",        SC_FUNC             },
+       { "SC_STORAGE",     SC_STORAGE          },
+       { "SC_DEF",         SC_DEF              },
+       { "SC_REF",         SC_REF              },
+       { "SC_ZEROPAGE",    SC_ZEROPAGE         },
     };
 
     unsigned I;
@@ -149,14 +149,6 @@ void DumpSymEntry (FILE* F, const SymEntry* E)
 
 
 
-int IsTypeDef (const SymEntry* E)
-/* Return true if the given entry is a typedef entry */
-{
-    return ((E->Flags & SC_TYPEDEF) == SC_TYPEDEF);
-}
-
-
-
 void ChangeSymType (SymEntry* Entry, type* Type)
 /* Change the type of the given symbol */
 {
index 299b0b08efedd1ed7d984842eaba3675ff34bb28..e81945d648da806c30f0fd91c3448981c4395e0b 100644 (file)
@@ -40,6 +40,9 @@
 
 #include <stdio.h>
 
+/* common */
+#include "inline.h"
+
 /* cc65 */
 #include "datatype.h"
 
@@ -81,7 +84,7 @@ struct Segments;
 
 #define SC_TYPE                0x4000U /* This is a type, struct, typedef, etc. */
 #define SC_STRUCT              0x4001U /* Struct or union */
-#define SC_SFLD                0x4002U /* Struct or union field */
+#define SC_STRUCTFIELD  0x4002U        /* Struct or union field */
 #define SC_TYPEDEF             0x4003U /* A typedef */
 
 #define SC_ZEROPAGE    0x8000U /* Symbol marked as zeropage */
@@ -103,13 +106,21 @@ struct SymEntry {
     /* Data that differs for the different symbol types */
     union {
 
-       /* Offset for locals or struct members */
-       int                     Offs;
+               /* Offset for locals or struct members */
+               int                     Offs;
+
+               /* Label name for static symbols */
+               unsigned                Label;
 
-       /* Label name for static symbols */
-       unsigned                Label;
+        /* Register bank offset and offset of the saved copy on stack for
+         * register variables.
+         */
+        struct {
+            int                 RegOffs;
+            int                 SaveOffs;
+        } R;
 
-       /* Value for constants (including enums) */
+               /* Value for constants (including enums) */
                long                    ConstVal;
 
        /* Data for structs/unions */
@@ -145,8 +156,35 @@ void FreeSymEntry (SymEntry* E);
 void DumpSymEntry (FILE* F, const SymEntry* E);
 /* Dump the given symbol table entry to the file in readable form */
 
-int IsTypeDef (const SymEntry* E);
+#if defined(HAVE_INLINE)
+INLINE int SymIsTypeDef (const SymEntry* Sym)
 /* Return true if the given entry is a typedef entry */
+{
+    return ((Sym->Flags & SC_TYPEDEF) == SC_TYPEDEF);
+}
+#else
+#  define SymIsTypeDef(Sym)     (((Sym)->Flags & SC_TYPEDEF) == SC_TYPEDEF)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int SymIsDef (const SymEntry* Sym)
+/* Return true if the given entry is defined */
+{
+    return ((Sym->Flags & SC_DEF) == SC_DEF);
+}
+#else
+#  define SymIsDef(Sym)     (((Sym)->Flags & SC_DEF) == SC_DEF)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int SymIsRef (const SymEntry* Sym)
+/* Return true if the given entry is referenced */
+{
+    return ((Sym->Flags & SC_REF) == SC_REF);
+}
+#else
+#  define SymIsRef(Sym)     (((Sym)->Flags & SC_REF) == SC_REF)
+#endif
 
 void ChangeSymType (SymEntry* Entry, type* Type);
 /* Change the type of the given symbol */
index eca971f654b2fa58168f2429309d6e4a6c2085ee..988190cd6a50a462790cde0a3c29433774e63bcb 100644 (file)
@@ -163,7 +163,7 @@ static void CheckSymTable (SymTable* Tab)
             * defined but not used.
             */
            if (((Flags & SC_AUTO) || (Flags & SC_STATIC)) && (Flags & SC_EXTERN) == 0) {
-               if ((Flags & SC_DEF) && !(Flags & SC_REF)) {
+               if (SymIsDef (Entry) && !SymIsRef (Entry)) {
                    if (Flags & SC_PARAM) {
                        Warning ("Parameter `%s' is never used", Entry->Name);
                    } else {
@@ -174,10 +174,10 @@ static void CheckSymTable (SymTable* Tab)
 
            /* If the entry is a label, check if it was defined in the function */
            if (Flags & SC_LABEL) {
-               if ((Flags & SC_DEF) == 0) {
+               if (!SymIsDef (Entry)) {
                    /* Undefined label */
                    Error ("Undefined label: `%s'", Entry->Name);
-               } else if ((Flags & SC_REF) == 0) {
+               } else if (!SymIsRef (Entry)) {
                    /* Defined but not used */
                    Warning ("`%s' is defined but never used", Entry->Name);
                }
@@ -614,7 +614,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
     SymEntry* Entry = FindSymInTable (LabelTab, Name, HashStr (Name));
     if (Entry) {
 
-       if ((Entry->Flags & SC_DEF) != 0 && (Flags & SC_DEF) != 0) {
+       if (SymIsDef (Entry) && (Flags & SC_DEF) != 0) {
            /* Trying to define the label more than once */
                    Error ("Label `%s' is defined more than once", Name);
        }
@@ -656,7 +656,18 @@ SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int O
 
        /* Set the symbol attributes */
        Entry->Type   = TypeDup (Type);
-       Entry->V.Offs = Offs;
+        if ((Flags & SC_AUTO) == SC_AUTO) {
+            Entry->V.Offs = Offs;
+        } else if ((Flags & SC_REGISTER) == SC_REGISTER) {
+            Entry->V.R.RegOffs  = Offs;
+            Entry->V.R.SaveOffs = oursp;        /* ### Cleaner! */
+        } else if ((Flags & SC_STATIC) == SC_STATIC) {
+            Entry->V.Label = Offs;
+        } else if ((Flags & SC_STRUCTFIELD) == SC_STRUCTFIELD) {
+            Entry->V.Offs = Offs;
+        } else {
+            Internal ("Invalid flags in AddLocalSym: %04X", Flags);
+        }
 
        /* Add the entry to the symbol table */
        AddSymEntry (SymTab, Entry);
@@ -856,10 +867,10 @@ void EmitExternals (void)
        unsigned Flags = Entry->Flags;
                if (Flags & SC_EXTERN) {
            /* Only defined or referenced externs */
-           if ((Flags & SC_REF) != 0 && (Flags & SC_DEF) == 0) {
+           if (SymIsRef (Entry) && !SymIsDef (Entry)) {
                /* An import */
                g_defimport (Entry->Name, Flags & SC_ZEROPAGE);
-           } else if (Flags & SC_DEF) {
+           } else if (SymIsDef (Entry)) {
                /* An export */
                g_defexport (Entry->Name, Flags & SC_ZEROPAGE);
            }