X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcodeinfo.c;h=3430dbeae1d8cf9ed58ca565d12043eb013e166e;hb=0529c2044a7006eb9092d419a59916acc8522c23;hp=0bbeffad1dbbc41be2c898d324d94fa66e0637f1;hpb=4c19a5b69938f653aa8718880cdc5e390a7f0ff8;p=cc65 diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 0bbeffad1..3430dbeae 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -67,6 +67,9 @@ struct FuncInfo { static const FuncInfo FuncInfoTable[] = { { "addysp", REG_Y, REG_NONE }, + { "bnega", REG_A, REG_AX }, + { "bnegax", REG_AX, REG_AX }, + { "bnegeax", REG_AX, REG_AX }, { "booleq", REG_NONE, REG_AX }, { "boolge", REG_NONE, REG_AX }, { "boolgt", REG_NONE, REG_AX }, @@ -77,45 +80,91 @@ static const FuncInfo FuncInfoTable[] = { { "boolugt", REG_NONE, REG_AX }, { "boolule", REG_NONE, REG_AX }, { "boolult", REG_NONE, REG_AX }, + { "complax", REG_AX, REG_AX }, { "decax1", REG_AX, REG_AX }, { "decax2", REG_AX, REG_AX }, { "decax3", REG_AX, REG_AX }, { "decax4", REG_AX, REG_AX }, { "decax5", REG_AX, REG_AX }, - { "decax6", REG_AX, REG_AX }, + { "decax6", REG_AX, REG_AX }, { "decax7", REG_AX, REG_AX }, - { "decax8", REG_AX, REG_AX }, - { "decaxy", REG_AXY, REG_AX }, - { "decsp2", REG_NONE, REG_A }, - { "decsp3", REG_NONE, REG_A }, - { "decsp4", REG_NONE, REG_A }, - { "decsp5", REG_NONE, REG_A }, - { "decsp6", REG_NONE, REG_A }, - { "decsp7", REG_NONE, REG_A }, - { "decsp8", REG_NONE, REG_A }, - { "incsp1", REG_NONE, REG_NONE }, - { "incsp2", REG_NONE, REG_Y }, - { "incsp3", REG_NONE, REG_Y }, - { "incsp4", REG_NONE, REG_Y }, - { "incsp5", REG_NONE, REG_Y }, - { "incsp6", REG_NONE, REG_Y }, - { "incsp7", REG_NONE, REG_Y }, - { "incsp8", REG_NONE, REG_Y }, - { "ldax0sp", REG_Y, REG_AX }, - { "ldaxysp", REG_Y, REG_AX }, - { "pusha", REG_A, REG_Y }, - { "pusha0", REG_A, REG_XY }, - { "pushax", REG_AX, REG_Y }, - { "pushw0sp", REG_NONE, REG_AXY }, - { "pushwysp", REG_Y, REG_AXY }, - { "tosicmp", REG_AX, REG_AXY }, + { "decax8", REG_AX, REG_AX }, + { "decaxy", REG_AXY, REG_AX }, + { "decsp1", REG_NONE, REG_Y }, + { "decsp2", REG_NONE, REG_A }, + { "decsp3", REG_NONE, REG_A }, + { "decsp4", REG_NONE, REG_A }, + { "decsp5", REG_NONE, REG_A }, + { "decsp6", REG_NONE, REG_A }, + { "decsp7", REG_NONE, REG_A }, + { "decsp8", REG_NONE, REG_A }, + { "incax1", REG_AX, REG_AX }, + { "incax2", REG_AX, REG_AX }, + { "incsp1", REG_NONE, REG_NONE }, + { "incsp2", REG_NONE, REG_Y }, + { "incsp3", REG_NONE, REG_Y }, + { "incsp4", REG_NONE, REG_Y }, + { "incsp5", REG_NONE, REG_Y }, + { "incsp6", REG_NONE, REG_Y }, + { "incsp7", REG_NONE, REG_Y }, + { "incsp8", REG_NONE, REG_Y }, + { "ldaidx", REG_AXY, REG_AX }, + { "ldauidx", REG_AXY, REG_AX }, + { "ldax0sp", REG_Y, REG_AX }, + { "ldaxi", REG_AX, REG_AXY }, + { "ldaxidx", REG_AXY, REG_AX }, + { "ldaxysp", REG_Y, REG_AX }, + { "leaasp", REG_A, REG_AX }, + { "negax", REG_AX, REG_AX }, + { "pusha", REG_A, REG_Y }, + { "pusha0", REG_A, REG_XY }, + { "pushax", REG_AX, REG_Y }, + { "pusheax", REG_AX, REG_Y }, + { "pushw0sp", REG_NONE, REG_AXY }, + { "pushwysp", REG_Y, REG_AXY }, + { "shrax1", REG_AX, REG_AX }, + { "shrax2", REG_AX, REG_AX }, + { "shrax3", REG_AX, REG_AX }, + { "shrax4", REG_AX, REG_AX }, + { "shreax1", REG_AX, REG_AX }, + { "shreax2", REG_AX, REG_AX }, + { "shreax3", REG_AX, REG_AX }, + { "shreax4", REG_AX, REG_AX }, + { "staspidx", REG_A | REG_Y, REG_Y }, + { "stax0sp", REG_AX, REG_Y }, + { "tosicmp", REG_AX, REG_AXY }, + { "tosdiva0", REG_AX, REG_AXY }, + { "tosdivax", REG_AX, REG_AXY }, + { "tosdiveax", REG_AX, REG_AXY }, + { "tosmula0", REG_AX, REG_AXY }, + { "tosmulax", REG_AX, REG_AXY }, + { "tosmuleax", REG_AX, REG_AXY }, + { "tosshreax", REG_AX, REG_AXY }, + { "tosumula0", REG_AX, REG_AXY }, + { "tosumulax", REG_AX, REG_AXY }, + { "tosumuleax", REG_AX, REG_AXY }, }; #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 */ +}; +static const ZPInfo ZPInfoTable[] = { + { 4, "ptr1" }, + { 7, "regbank" }, + { 7, "regsave" }, + { 2, "sp" }, + { 4, "sreg" }, + { 4, "tmp1" }, +}; +#define ZPInfoCount (sizeof(ZPInfoTable) / sizeof(ZPInfoTable[0])) /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -142,15 +191,16 @@ void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg) if (Name[0] == '_') { /* Search in the symbol table, skip the leading underscore */ - SymEntry* E = FindSym (Name+1); + SymEntry* E = FindGlobalSym (Name+1); /* Did we find it in the top level table? */ - if (E && E->Owner->PrevTab == 0 && IsTypeFunc (E->Type)) { + if (E && IsTypeFunc (E->Type)) { /* A function may use the A or A/X registers if it is a fastcall - * function. Otherwise it does not use any registers passed by - * the caller. However, we assume that any function will destroy - * all registers. + * function. If it is not a fastcall function but a variadic one, + * it will use the Y register (the parameter size is passed here). + * In all other cases, no registers are used. However, we assume + * that any function will destroy all registers. */ FuncDesc* D = E->V.F.Func; if ((D->Flags & FD_FASTCALL) != 0 && D->ParamCount > 0) { @@ -161,6 +211,8 @@ void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg) } else { *Use = REG_AX; } + } else if ((D->Flags & FD_VARIADIC) != 0) { + *Use = REG_Y; } else { /* Will not use any registers */ *Use = REG_NONE; @@ -195,6 +247,27 @@ void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg) +int IsZPName (const char* Name) +/* Return true if the given name is a zero page symbol */ +{ + unsigned I; + const ZPInfo* Info; + + /* Because of the low number of symbols, we do a linear search here */ + for (I = 0, Info = ZPInfoTable; I < ZPInfoCount; ++I, ++Info) { + if (strncmp (Name, Info->Name, Info->Len) == 0 && + (Name[Info->Len] == '\0' || Name[Info->Len] == '+')) { + /* Found */ + return 1; + } + } + + /* Not found */ + return 0; +} + + + static unsigned char GetRegInfo2 (CodeSeg* S, CodeEntry* E, int Index, @@ -211,17 +284,17 @@ static unsigned char GetRegInfo2 (CodeSeg* S, /* Check if we have already visited the current code entry. If so, * bail out. */ - if (CodeEntryHasMark (E)) { + if (CE_HasMark (E)) { break; } /* Mark this entry as already visited */ - CodeEntrySetMark (E); + CE_SetMark (E); CollAppend (Visited, E); /* Evaluate the used registers */ R = E->Use; - if (E->OPC == OPC_RTS || + if (E->OPC == OP65_RTS || ((E->Info & OF_BRA) != 0 && E->JumpTo == 0)) { /* This instruction will leave the function */ R |= S->ExitRegs; @@ -251,7 +324,7 @@ static unsigned char GetRegInfo2 (CodeSeg* S, } /* If the instruction is an RTS or RTI, we're done */ - if (E->OPC == OPC_RTS || E->OPC == OPC_RTI) { + if ((E->Info & OF_RET) != 0) { break; } @@ -290,9 +363,9 @@ static unsigned char GetRegInfo2 (CodeSeg* S, return REG_AXY; } if (Index < 0) { - Index = GetCodeEntryIndex (S, E); + Index = CS_GetEntryIndex (S, E); } - if ((E = GetCodeEntry (S, ++Index)) == 0) { + if ((E = CS_GetEntry (S, ++Index)) == 0) { Internal ("GetRegInfo2: No next entry!"); } U2 = GetRegInfo2 (S, E, Index, Visited, Used, Unused); @@ -307,9 +380,9 @@ static unsigned char GetRegInfo2 (CodeSeg* S, /* Just go to the next instruction */ if (Index < 0) { - Index = GetCodeEntryIndex (S, E); + Index = CS_GetEntryIndex (S, E); } - E = GetCodeEntry (S, ++Index); + E = CS_GetEntry (S, ++Index); if (E == 0) { /* No next entry */ Internal ("GetRegInfo2: No next entry!"); @@ -326,8 +399,8 @@ static unsigned char GetRegInfo2 (CodeSeg* S, static unsigned char GetRegInfo1 (CodeSeg* S, - CodeEntry* E, - int Index, + CodeEntry* E, + int Index, Collection* Visited, unsigned char Used, unsigned char Unused) @@ -343,7 +416,7 @@ static unsigned char GetRegInfo1 (CodeSeg* S, unsigned NewCount = CollCount (Visited); while (NewCount-- > Count) { CodeEntry* E = CollAt (Visited, NewCount); - CodeEntryResetMark (E); + CE_ResetMark (E); CollDelete (Visited, NewCount); } @@ -363,11 +436,11 @@ unsigned char GetRegInfo (struct CodeSeg* S, unsigned Index) unsigned char R; /* Get the code entry for the given index */ - if (Index >= GetCodeEntryCount (S)) { + if (Index >= CS_GetEntryCount (S)) { /* There is no such code entry */ return REG_NONE; } - E = GetCodeEntry (S, Index); + E = CS_GetEntry (S, Index); /* Initialize the data structure used to collection information */ InitCollection (&Visited); @@ -408,3 +481,4 @@ int RegYUsed (struct CodeSeg* S, unsigned Index) +