]> git.sur5r.net Git - cc65/commitdiff
Finished indirect function calls.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 25 Sep 2001 10:30:48 +0000 (10:30 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 25 Sep 2001 10:30:48 +0000 (10:30 +0000)
Debugged zero page location tracking.

git-svn-id: svn://svn.cc65.org/cc65/trunk@968 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codeent.c
src/cc65/codegen.c
src/cc65/codegen.h
src/cc65/codeinfo.c
src/cc65/codeinfo.h
src/cc65/codeseg.c
src/cc65/expr.c

index e37d079f50a16df7edef3b5dc7400062069a075f..7cca0bd788863c11b41a2b60a53314736de64d02 100644 (file)
@@ -137,7 +137,7 @@ static int NumArg (const char* Arg, unsigned long* Num)
 static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
 /* Set the Use and Chg in E */
 {
-    unsigned short Use;
+    const ZPInfo* Info;
 
     /* If this is a subroutine call, or a jump to an external function,
      * lookup the information about this function and use it. The jump itself
@@ -162,20 +162,21 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
            case AM65_ZPX:
            case AM65_ABSX:
            case AM65_ABSY:
-               if (IsZPName (E->Arg, &Use) && Use != REG_NONE) {
+               Info = GetZPInfo (E->Arg);
+               if (Info && Info->ByteUse != REG_NONE) {
                    if (E->OPC == OP65_ASL || E->OPC == OP65_DEC ||
-                       E->OPC == OP65_INC || E->OPC == OP65_LSR ||
-                       E->OPC == OP65_ROL || E->OPC == OP65_ROR ||
-                       E->OPC == OP65_TRB || E->OPC == OP65_TSB) {
-                       /* The zp loc is both, input and output */
-                       E->Chg |= Use;
-                       E->Use |= Use;
+                       E->OPC == OP65_INC || E->OPC == OP65_LSR ||
+                       E->OPC == OP65_ROL || E->OPC == OP65_ROR ||
+                       E->OPC == OP65_TRB || E->OPC == OP65_TSB) {
+                       /* The zp loc is both, input and output */
+                       E->Chg |= Info->ByteUse;
+                       E->Use |= Info->ByteUse;
                    } else if ((E->Info & OF_STORE) != 0) {
-                       /* Just output */
-                       E->Chg |= Use;
+                       /* Just output */
+                       E->Chg |= Info->ByteUse;
                    } else {
-                       /* Input only */
-                       E->Use |= Use;
+                       /* Input only */
+                       E->Use |= Info->ByteUse;
                    }
                }
                break;
@@ -183,9 +184,10 @@ static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
            case AM65_ZPX_IND:
            case AM65_ZP_INDY:
            case AM65_ZP_IND:
-               if (IsZPName (E->Arg, &Use) && Use != REG_NONE) {
+               Info = GetZPInfo (E->Arg);
+               if (Info && Info->ByteUse != REG_NONE) {
                    /* These addressing modes will never change the zp loc */
-                   E->Use |= Use;
+                   E->Use |= Info->WordUse;
                }
                break;
 
@@ -774,7 +776,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
            Out->RegX = In->RegA;
            break;
 
-       case OP65_TAY:       
+       case OP65_TAY:
            Out->RegY = In->RegA;
            break;
 
@@ -821,17 +823,10 @@ static char* RegInfoDesc (unsigned U, char* Buf)
     strcat (Buf, U & REG_A?       "A" : "_");
     strcat (Buf, U & REG_X?       "X" : "_");
     strcat (Buf, U & REG_Y?       "Y" : "_");
-    strcat (Buf, U & REG_SP?      "S" : "_");
     strcat (Buf, U & REG_TMP1?    "T1" : "__");
-    strcat (Buf, U & REG_TMP2?    "T2" : "__");
-    strcat (Buf, U & REG_TMP3?    "T3" : "__");
-    strcat (Buf, U & REG_TMP4?    "T4" : "__");
     strcat (Buf, U & REG_PTR1?    "1" : "_");
     strcat (Buf, U & REG_PTR2?    "2" : "_");
-    strcat (Buf, U & REG_PTR3?    "3" : "_");
-    strcat (Buf, U & REG_PTR4?    "4" : "_");
     strcat (Buf, U & REG_SAVE?    "V"  : "_");
-    strcat (Buf, U & REG_BANK?    "B" : "_");
 
     return Buf;
 }
index 74a1710d44733371e5675df20aca77d9f6e87b55..d936c1572609d1a1fd4513439a99d603ba8ef426 100644 (file)
@@ -2373,15 +2373,33 @@ void g_call (unsigned Flags, const char* Label, unsigned ArgSize)
 
 
 
-void g_callind (unsigned Flags, unsigned ArgSize)
-/* Call subroutine with address in AX */
-{
-    if ((Flags & CF_FIXARGC) == 0) {
-       /* Pass arg count */
-       ldyconst (ArgSize);
+void g_callind (unsigned Flags, unsigned ArgSize, int Offs)
+/* Call subroutine indirect */
+{
+    if ((Flags & CF_LOCAL) == 0) {
+       /* Address is in a/x */
+       if ((Flags & CF_FIXARGC) == 0) {
+           /* Pass arg count */
+           ldyconst (ArgSize);
+       }
+       AddCodeLine ("jsr callax");
+    } else {
+       /* The address is on stack, offset is on Val */
+       Offs -= oursp;
+       CheckLocalOffs (Offs);
+       AddCodeLine ("pha");
+       AddCodeLine ("ldy #$%02X", Offs);
+       AddCodeLine ("lda (sp),y");
+       AddCodeLine ("sta jmpvec+1");
+       AddCodeLine ("iny");
+       AddCodeLine ("lda (sp),y");
+       AddCodeLine ("sta jmpvec+2");
+       AddCodeLine ("pla");
+       AddCodeLine ("jsr jmpvec");
     }
-    AddCodeLine ("jsr callax");        /* do the call */
-    oursp += ArgSize;                  /* callee pops args */
+
+    /* Callee pops args */
+    oursp += ArgSize;
 }
 
 
index 91274ec42f48a5a5f21944e44606cddd8444756e..704032ea4ad3f088a1340de967f3e8cf30f739c6 100644 (file)
@@ -370,8 +370,8 @@ void g_swap (unsigned flags);
 void g_call (unsigned Flags, const char* Label, unsigned ArgSize);
 /* Call the specified subroutine name */
 
-void g_callind (unsigned Flags, unsigned ArgSize);
-/* Call subroutine with address in AX */
+void g_callind (unsigned Flags, unsigned ArgSize, int Offs);
+/* Call subroutine indirect */
 
 void g_jump (unsigned Label);
 /* Jump to specified internal label number */
index abf8a3bf5bac00aa2c69cd7946e9bc533654fc47..9dd6e9b95214e85df3715b4cbbc37edce4995a78 100644 (file)
@@ -112,9 +112,9 @@ static const FuncInfo FuncInfoTable[] = {
     { "incsp6",                REG_NONE,             REG_Y                          },
     { "incsp7",                REG_NONE,             REG_Y                          },
     { "incsp8",                REG_NONE,             REG_Y                          },
-    { "laddeq",                REG_EAXY | REG_PTR1,  REG_EAXY                       },
-    { "laddeq1",               REG_Y | REG_PTR1,     REG_EAXY                       },
-    { "laddeqa",        REG_AY | REG_PTR1,    REG_EAXY                       },
+    { "laddeq",                REG_EAXY|REG_PTR1_LO, REG_EAXY | REG_PTR1_HI         },
+    { "laddeq1",               REG_Y | REG_PTR1_LO,  REG_EAXY | REG_PTR1_HI         },
+    { "laddeqa",        REG_AY | REG_PTR1_LO, REG_EAXY | REG_PTR1_HI         },
     { "ldaidx",         REG_AXY,              REG_AX | REG_PTR1                     },
     { "ldauidx",        REG_AXY,              REG_AX | REG_PTR1                     },
     { "ldax0sp",               REG_Y,                REG_AX                         },
@@ -143,6 +143,7 @@ static const FuncInfo FuncInfoTable[] = {
     { "shreax4",        REG_EAX,              REG_AX | REG_TMP1                     },
     { "staspidx",       REG_A | REG_Y,        REG_Y | REG_TMP1 | REG_PTR1    },
     { "stax0sp",        REG_AX,               REG_Y                         },
+    { "staxysp",        REG_AXY,              REG_Y                         },
     { "tosicmp",               REG_AX,               REG_AXY | REG_SREG             },
     { "tosdiva0",       REG_AX,                      REG_ALL                        },
     { "tosdivax",       REG_AX,                      REG_ALL                        },
@@ -158,26 +159,23 @@ static const FuncInfo FuncInfoTable[] = {
 #define FuncInfoCount  (sizeof(FuncInfoTable) / sizeof(FuncInfoTable[0]))
 
 /* Table with names of zero page locations used by the compiler */
-typedef struct ZPInfo ZPInfo;
-struct ZPInfo {
-    unsigned char  Len;                /* Length of the following string */
-    char           Name[11];    /* Name of zero page symbol */
-    unsigned short RegInfo;     /* Register info for this symbol */
-};
 static const ZPInfo ZPInfoTable[] = {
-    {          4,      "ptr1",         REG_PTR1        },
-    {          4,      "ptr2",         REG_PTR2        },
-    {          4,      "ptr3",         REG_PTR3        },
-    {          4,      "ptr4",         REG_PTR4        },
-    {   7,      "regbank",      REG_BANK        },
-    {   7,      "regsave",      REG_SAVE        },
-    {   2,      "sp",           REG_SP          },
-    {   0,      "sreg",         REG_SREG_LO     },
-    {  0,      "sreg+1",       REG_SREG_HI     },
-    {   4,      "tmp1",         REG_TMP1        },
-    {   4,      "tmp2",         REG_TMP2        },
-    {   4,      "tmp3",         REG_TMP3        },
-    {   4,      "tmp4",         REG_TMP4        },
+    {          0, "ptr1",      REG_PTR1_LO,    REG_PTR1        },
+    {   0, "ptr1+1",    REG_PTR1_HI,   REG_PTR1        },
+    {          0, "ptr2",      REG_PTR2_LO,    REG_PTR2        },
+    {   0, "ptr2+1",    REG_PTR2_HI,   REG_PTR2        },
+    {          4, "ptr3",      REG_NONE,       REG_NONE        },
+    {          4, "ptr4",      REG_NONE,       REG_NONE        },
+    {   7, "regbank",   REG_NONE,      REG_NONE        },
+    {   0, "regsave",   REG_SAVE_LO,   REG_SAVE        },
+    {   0, "regsave+1", REG_SAVE_HI,   REG_SAVE        },
+    {   2, "sp",        REG_NONE,      REG_NONE        },
+    {   0, "sreg",      REG_SREG_LO,   REG_SREG        },
+    {  0, "sreg+1",    REG_SREG_HI,    REG_SREG        },
+    {   0, "tmp1",      REG_TMP1,      REG_TMP1        },
+    {   0, "tmp2",      REG_NONE,      REG_NONE        },
+    {   0, "tmp3",      REG_NONE,      REG_NONE        },
+    {   0, "tmp4",      REG_NONE,      REG_NONE        },
 };
 #define ZPInfoCount            (sizeof(ZPInfoTable) / sizeof(ZPInfoTable[0]))
 
@@ -259,10 +257,10 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg)
        }
     }
 
-    /* Function not found - assume all CPU registers are input, and all
+    /* Function not found - assume that the primary register is input, and all
      * registers are changed
      */
-    *Use = REG_AXY;
+    *Use = REG_EAXY;
     *Chg = REG_ALL;
 }
 
@@ -294,27 +292,14 @@ static int CompareZPInfo (const void* Name, const void* Info)
 
 
 
-int IsZPName (const char* Name, unsigned short* RegInfo)
-/* Return true if the given name is a zero page symbol. If the RegInfo
- * pointer is not NULL, it is filled with the register info for the
- * zero page location found.
+const ZPInfo* GetZPInfo (const char* Name)
+/* If the given name is a zero page symbol, return a pointer to the info
+ * struct for this symbol, otherwise return NULL.
  */
 {
     /* Search for the zp location in the list */
-    const ZPInfo* Info = bsearch (Name, ZPInfoTable, ZPInfoCount,
-                                 sizeof(ZPInfo), CompareZPInfo);
-
-    /* Did we find it? */
-    if (Info) {
-       /* Found, store register info if requested. */
-       if (RegInfo) {
-           *RegInfo = Info->RegInfo;
-       }
-       return 1;
-    } else {
-       /* Not found */
-       return 0;
-    }
+    return bsearch (Name, ZPInfoTable, ZPInfoCount,
+                   sizeof(ZPInfo), CompareZPInfo);
 }
 
 
index b4df0dd0321ba7c1a66ea4119918d70acf6c46ab..c445bd4312760a696652b9102a81cb6ce26aac25 100644 (file)
@@ -60,32 +60,42 @@ struct CodeSeg;
 #define REG_X                  0x0002U
 #define REG_Y                  0x0004U
 #define REG_TMP1               0x0008U
-#define REG_TMP2        0x0010U
-#define REG_TMP3        0x0020U
-#define REG_TMP4        0x0040U
-#define REG_PTR1               0x0080U
-#define REG_PTR2       0x0100U
-#define REG_PTR3       0x0200U
-#define REG_PTR4       0x0400U
-#define REG_SREG_LO            0x0800U
-#define REG_SREG_HI     0x1000U
-#define REG_SP          0x2000U
-#define REG_SAVE        0x4000U
-#define REG_BANK        0x8000U
+#define REG_PTR1_LO            0x0010U
+#define REG_PTR1_HI            0x0020U
+#define REG_PTR2_LO     0x0040U
+#define REG_PTR2_HI     0x0080U
+#define REG_SREG_LO            0x0100U
+#define REG_SREG_HI     0x0200U
+#define REG_SAVE_LO     0x0400U
+#define REG_SAVE_HI     0x0800U
 
 /* Combined register defines */
+#define REG_PTR1        (REG_PTR1_LO | REG_PTR1_HI)
+#define REG_PTR2        (REG_PTR2_LO | REG_PTR2_HI)
 #define REG_SREG        (REG_SREG_LO | REG_SREG_HI)
+#define REG_SAVE        (REG_SAVE_LO | REG_SAVE_HI)
 #define        REG_AX          (REG_A | REG_X)
 #define REG_AY          (REG_A | REG_Y)
 #define REG_XY         (REG_X | REG_Y)
 #define REG_AXY                (REG_AX | REG_Y)
 #define REG_EAX         (REG_AX | REG_SREG)
 #define REG_EAXY        (REG_EAX | REG_Y)
-#define REG_ZP          0xFFF0U
+#define REG_ZP          0xFFF8U
 #define REG_ALL         0xFFFFU
 
 
 
+/* Zero page register info */
+typedef struct ZPInfo ZPInfo;
+struct ZPInfo {
+    unsigned char  Len;                /* Length of the following string */
+    char           Name[11];    /* Name of zero page symbol */
+    unsigned short ByteUse;     /* Register info for this symbol */
+    unsigned short WordUse;     /* Register info for 16 bit access */
+};
+
+
+
 /*****************************************************************************/
 /*                                          Code                                    */
 /*****************************************************************************/
@@ -98,10 +108,9 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg);
  * load all registers.
  */
 
-int IsZPName (const char* Name, unsigned short* RegInfo);
-/* Return true if the given name is a zero page symbol. If the RegInfo
- * pointer is not NULL, it is filled with the register info for the
- * zero page location found.
+const ZPInfo* GetZPInfo (const char* Name);
+/* If the given name is a zero page symbol, return a pointer to the info
+ * struct for this symbol, otherwise return NULL.
  */
 
 unsigned GetRegInfo (struct CodeSeg* S, unsigned Index, unsigned Wanted);
index f29c6767e3492145ec3885a8d26f46e9c8cccf21..567b2e96ba9690595dcc4962ce855a36c11a1de0 100644 (file)
@@ -323,7 +323,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
                if ((OPC->Info & OF_BRA) != 0) {
                    /* Branch */
                    AM = AM65_BRA;
-               } else if (IsZPName (Arg, 0)) {
+               } else if (GetZPInfo(Arg) != 0) {
                    AM = AM65_ZP;
                } else {
                    AM = AM65_ABS;
@@ -338,7 +338,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
                    Reg = toupper (*L);
                    L = SkipSpace (L+1);
                    if (Reg == 'X') {
-                       if (IsZPName (Arg, 0)) {
+                       if (GetZPInfo(Arg) != 0) {
                            AM = AM65_ZPX;
                        } else {
                            AM = AM65_ABSX;
index ed0b1cf1e345fcfbb659ed6bb5d6ad704e21bb56..745d42b45a1b1a53ff0977d5d9327e47c34be3bf 100644 (file)
@@ -774,35 +774,29 @@ static void FunctionCall (int k, ExprDesc* lval)
        /* If the function is not a fastcall function, load the pointer to
         * the function into the primary.
         */
-       if (!IsFastCallFunc (lval->Type)) {
+       if (!IsFastCall) {
 
            /* Not a fastcall function - we may use the primary */
                    if (PtrOnStack) {
-               /* If we have no parameters, the pointer is still in the
-                * primary. Remove the code to push it and correct the
-                * stack pointer.
-                */
-               if (ParamSize == 0) {
-                   RemoveCode (Mark);
-                   pop (CF_PTR);
-                   PtrOnStack = 0;
-               } else {
-                   /* Load from the saved copy */
-                   g_getlocal (CF_PTR, PtrOffs);
-               }
+               /* If we have no parameters, the pointer is still in the
+                * primary. Remove the code to push it and correct the
+                * stack pointer.
+                */
+               if (ParamSize == 0) {
+                   RemoveCode (Mark);
+                   pop (CF_PTR);
+                   PtrOnStack = 0;
+               } else {
+                   /* Load from the saved copy */
+                   g_getlocal (CF_PTR, PtrOffs);
+               }
            } else {
                /* Load from original location */
                exprhs (CF_NONE, k, lval);
            }
 
            /* Call the function */
-           g_callind (TypeOf (lval->Type), ParamSize);
-
-           /* If we have a pointer on stack, remove it */
-           if (PtrOnStack) {
-               g_space (- (int) sizeofarg (CF_PTR));
-               pop (CF_PTR);
-           }
+           g_callind (TypeOf (lval->Type), ParamSize, PtrOffs);
 
        } else {
 
@@ -811,11 +805,16 @@ static void FunctionCall (int k, ExprDesc* lval)
             * Since fastcall functions may never be variadic, we can use the
             * index register for this purpose.
             */
-           Error ("Not implemented");
-           pop (CF_PTR);
+           g_callind (CF_LOCAL, ParamSize, PtrOffs);
        }
 
-       /* Skip T_PTR */            
+       /* If we have a pointer on stack, remove it */
+       if (PtrOnStack) {
+           g_space (- (int) sizeofarg (CF_PTR));
+           pop (CF_PTR);
+       }
+                                                             
+       /* Skip T_PTR */
        ++lval->Type;
 
     } else {