mirror of
https://github.com/cc65/cc65.git
synced 2025-02-05 20:31:53 +00:00
Extend usage information
git-svn-id: svn://svn.cc65.org/cc65/trunk@962 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
f3b401cd21
commit
51b8bd4046
@ -306,7 +306,7 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs)
|
|||||||
RegContents* Out;
|
RegContents* Out;
|
||||||
|
|
||||||
/* Function register usage */
|
/* Function register usage */
|
||||||
unsigned char Use, Chg;
|
unsigned short Use, Chg;
|
||||||
|
|
||||||
/* If we don't have a register info struct, allocate one. */
|
/* If we don't have a register info struct, allocate one. */
|
||||||
if (E->RI == 0) {
|
if (E->RI == 0) {
|
||||||
|
@ -71,9 +71,9 @@ struct CodeEntry {
|
|||||||
unsigned long Num; /* Numeric argument */
|
unsigned long Num; /* Numeric argument */
|
||||||
unsigned short Flags; /* Flags */
|
unsigned short Flags; /* Flags */
|
||||||
unsigned short Info; /* Additional code info */
|
unsigned short Info; /* Additional code info */
|
||||||
|
unsigned short Use; /* Registers used */
|
||||||
|
unsigned short Chg; /* Registers changed/destroyed */
|
||||||
unsigned char Size; /* Estimated size */
|
unsigned char Size; /* Estimated size */
|
||||||
unsigned char Use; /* Registers used */
|
|
||||||
unsigned char Chg; /* Registers changed/destroyed */
|
|
||||||
CodeLabel* JumpTo; /* Jump label */
|
CodeLabel* JumpTo; /* Jump label */
|
||||||
Collection Labels; /* Labels for this instruction */
|
Collection Labels; /* Labels for this instruction */
|
||||||
LineInfo* LI; /* Source line info for this insn */
|
LineInfo* LI; /* Source line info for this insn */
|
||||||
|
@ -61,8 +61,8 @@
|
|||||||
typedef struct FuncInfo FuncInfo;
|
typedef struct FuncInfo FuncInfo;
|
||||||
struct FuncInfo {
|
struct FuncInfo {
|
||||||
const char* Name; /* Function name */
|
const char* Name; /* Function name */
|
||||||
unsigned char Use; /* Register usage */
|
unsigned short Use; /* Register usage */
|
||||||
unsigned char Chg; /* Changed/destroyed registers */
|
unsigned short Chg; /* Changed/destroyed registers */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const FuncInfo FuncInfoTable[] = {
|
static const FuncInfo FuncInfoTable[] = {
|
||||||
@ -105,13 +105,13 @@ static const FuncInfo FuncInfoTable[] = {
|
|||||||
{ "incax1", REG_AX, REG_AX },
|
{ "incax1", REG_AX, REG_AX },
|
||||||
{ "incax2", REG_AX, REG_AX },
|
{ "incax2", REG_AX, REG_AX },
|
||||||
{ "incsp1", REG_NONE, REG_NONE },
|
{ "incsp1", REG_NONE, REG_NONE },
|
||||||
{ "incsp2", REG_NONE, REG_Y },
|
{ "incsp2", REG_NONE, REG_Y },
|
||||||
{ "incsp3", REG_NONE, REG_Y },
|
{ "incsp3", REG_NONE, REG_Y },
|
||||||
{ "incsp4", REG_NONE, REG_Y },
|
{ "incsp4", REG_NONE, REG_Y },
|
||||||
{ "incsp5", REG_NONE, REG_Y },
|
{ "incsp5", REG_NONE, REG_Y },
|
||||||
{ "incsp6", REG_NONE, REG_Y },
|
{ "incsp6", REG_NONE, REG_Y },
|
||||||
{ "incsp7", REG_NONE, REG_Y },
|
{ "incsp7", REG_NONE, REG_Y },
|
||||||
{ "incsp8", REG_NONE, REG_Y },
|
{ "incsp8", REG_NONE, REG_Y },
|
||||||
{ "ldaidx", REG_AXY, REG_AX },
|
{ "ldaidx", REG_AXY, REG_AX },
|
||||||
{ "ldauidx", REG_AXY, REG_AX },
|
{ "ldauidx", REG_AXY, REG_AX },
|
||||||
{ "ldax0sp", REG_Y, REG_AX },
|
{ "ldax0sp", REG_Y, REG_AX },
|
||||||
@ -185,7 +185,7 @@ static int CompareFuncInfo (const void* Key, const void* Info)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg)
|
void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg)
|
||||||
/* For the given function, lookup register information and store it into
|
/* For the given function, lookup register information and store it into
|
||||||
* the given variables. If the function is unknown, assume it will use and
|
* the given variables. If the function is unknown, assume it will use and
|
||||||
* load all registers.
|
* load all registers.
|
||||||
@ -276,28 +276,28 @@ int IsZPName (const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned char GetRegInfo1 (CodeSeg* S,
|
static unsigned GetRegInfo1 (CodeSeg* S,
|
||||||
CodeEntry* E,
|
CodeEntry* E,
|
||||||
int Index,
|
int Index,
|
||||||
Collection* Visited,
|
Collection* Visited,
|
||||||
unsigned char Used,
|
unsigned Used,
|
||||||
unsigned char Unused);
|
unsigned Unused);
|
||||||
/* Recursively called subfunction for GetRegInfo. */
|
/* Recursively called subfunction for GetRegInfo. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned char GetRegInfo2 (CodeSeg* S,
|
static unsigned GetRegInfo2 (CodeSeg* S,
|
||||||
CodeEntry* E,
|
CodeEntry* E,
|
||||||
int Index,
|
int Index,
|
||||||
Collection* Visited,
|
Collection* Visited,
|
||||||
unsigned char Used,
|
unsigned Used,
|
||||||
unsigned char Unused)
|
unsigned Unused)
|
||||||
/* Recursively called subfunction for GetRegInfo. */
|
/* Recursively called subfunction for GetRegInfo. */
|
||||||
{
|
{
|
||||||
/* Follow the instruction flow recording register usage. */
|
/* Follow the instruction flow recording register usage. */
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
unsigned char R;
|
unsigned R;
|
||||||
|
|
||||||
/* Check if we have already visited the current code entry. If so,
|
/* Check if we have already visited the current code entry. If so,
|
||||||
* bail out.
|
* bail out.
|
||||||
@ -372,8 +372,8 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
|
|||||||
if (E->JumpTo) {
|
if (E->JumpTo) {
|
||||||
|
|
||||||
/* Recursively determine register usage at the branch target */
|
/* Recursively determine register usage at the branch target */
|
||||||
unsigned char U1;
|
unsigned U1;
|
||||||
unsigned char U2;
|
unsigned U2;
|
||||||
|
|
||||||
U1 = GetRegInfo1 (S, E->JumpTo->Owner, -1, Visited, Used, Unused);
|
U1 = GetRegInfo1 (S, E->JumpTo->Owner, -1, Visited, Used, Unused);
|
||||||
if (U1 == REG_AXY) {
|
if (U1 == REG_AXY) {
|
||||||
@ -416,19 +416,19 @@ static unsigned char GetRegInfo2 (CodeSeg* S,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned char GetRegInfo1 (CodeSeg* S,
|
static unsigned GetRegInfo1 (CodeSeg* S,
|
||||||
CodeEntry* E,
|
CodeEntry* E,
|
||||||
int Index,
|
int Index,
|
||||||
Collection* Visited,
|
Collection* Visited,
|
||||||
unsigned char Used,
|
unsigned Used,
|
||||||
unsigned char Unused)
|
unsigned Unused)
|
||||||
/* Recursively called subfunction for GetRegInfo. */
|
/* Recursively called subfunction for GetRegInfo. */
|
||||||
{
|
{
|
||||||
/* Remember the current count of the line collection */
|
/* Remember the current count of the line collection */
|
||||||
unsigned Count = CollCount (Visited);
|
unsigned Count = CollCount (Visited);
|
||||||
|
|
||||||
/* Call the worker routine */
|
/* Call the worker routine */
|
||||||
unsigned char R = GetRegInfo2 (S, E, Index, Visited, Used, Unused);
|
unsigned R = GetRegInfo2 (S, E, Index, Visited, Used, Unused);
|
||||||
|
|
||||||
/* Restore the old count, unmarking all new entries */
|
/* Restore the old count, unmarking all new entries */
|
||||||
unsigned NewCount = CollCount (Visited);
|
unsigned NewCount = CollCount (Visited);
|
||||||
@ -444,14 +444,14 @@ static unsigned char GetRegInfo1 (CodeSeg* S,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char GetRegInfo (struct CodeSeg* S, unsigned Index)
|
unsigned GetRegInfo (struct CodeSeg* S, unsigned Index)
|
||||||
/* Determine register usage information for the instructions starting at the
|
/* Determine register usage information for the instructions starting at the
|
||||||
* given index.
|
* given index.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
CodeEntry* E;
|
CodeEntry* E;
|
||||||
Collection Visited; /* Visited entries */
|
Collection Visited; /* Visited entries */
|
||||||
unsigned char R;
|
unsigned R;
|
||||||
|
|
||||||
/* Get the code entry for the given index */
|
/* Get the code entry for the given index */
|
||||||
if (Index >= CS_GetEntryCount (S)) {
|
if (Index >= CS_GetEntryCount (S)) {
|
||||||
@ -500,3 +500,4 @@ int RegYUsed (struct CodeSeg* S, unsigned Index)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,37 +49,48 @@ struct CodeSeg;
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Defines for registers. */
|
/* Defines for registers. */
|
||||||
#define REG_NONE 0x00U
|
#define REG_NONE 0x0000U
|
||||||
#define REG_A 0x01U
|
#define REG_A 0x0001U
|
||||||
#define REG_X 0x02U
|
#define REG_X 0x0002U
|
||||||
#define REG_Y 0x04U
|
#define REG_Y 0x0004U
|
||||||
#define REG_SREG_LO 0x08U
|
#define REG_SREG_LO 0x0008U
|
||||||
#define REG_SREG_HI 0x10U
|
#define REG_SREG_HI 0x0010U
|
||||||
#define REG_TMP1 0x20U
|
#define REG_TMP1 0x0020U
|
||||||
#define REG_PTR1_LO 0x40U
|
#define REG_TMP2 0x0040U
|
||||||
#define REG_PTR1_HI 0x80U
|
#define REG_TMP3 0x0080U
|
||||||
|
#define REG_PTR1_LO 0x0100U
|
||||||
|
#define REG_PTR1_HI 0x0200U
|
||||||
|
#define REG_PTR2_LO 0x0400U
|
||||||
|
#define REG_PTR2_HI 0x0800U
|
||||||
|
#define REG_PTR3_LO 0x1000U
|
||||||
|
#define REG_PTR3_HI 0x2000U
|
||||||
|
#define REG_PTR4_LO 0x4000U
|
||||||
|
#define REG_PTR4_HI 0x8000U
|
||||||
#define REG_AX (REG_A | REG_X)
|
#define REG_AX (REG_A | REG_X)
|
||||||
#define REG_EAX (REG_A | REG_X | REG_SREG_LO | REG_SREG_HI)
|
#define REG_EAX (REG_A | REG_X | REG_SREG_LO | REG_SREG_HI)
|
||||||
#define REG_XY (REG_X | REG_Y)
|
#define REG_XY (REG_X | REG_Y)
|
||||||
#define REG_AXY (REG_A | REG_X | REG_Y)
|
#define REG_AXY (REG_A | REG_X | REG_Y)
|
||||||
#define REG_SREG (REG_SREG_LO | REG_SREG_HI)
|
#define REG_SREG (REG_SREG_LO | REG_SREG_HI)
|
||||||
#define REG_PTR1 (REG_PTR1_LO | REG_PTR1_HI)
|
#define REG_PTR1 (REG_PTR1_LO | REG_PTR1_HI)
|
||||||
|
#define REG_PTR2 (REG_PTR2_LO | REG_PTR2_HI)
|
||||||
|
#define REG_PTR3 (REG_PTR3_LO | REG_PTR3_HI)
|
||||||
|
#define REG_PTR4 (REG_PTR4_LO | REG_PTR4_HI)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg);
|
void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg);
|
||||||
/* For the given function, lookup register information and store it into
|
/* For the given function, lookup register information and store it into
|
||||||
* the given variables. If the function is unknown, assume it will use and
|
* the given variables. If the function is unknown, assume it will use and
|
||||||
* load all registers.
|
* load all registers.
|
||||||
@ -88,7 +99,7 @@ void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg);
|
|||||||
int IsZPName (const char* Name);
|
int IsZPName (const char* Name);
|
||||||
/* Return true if the given name is a zero page symbol */
|
/* Return true if the given name is a zero page symbol */
|
||||||
|
|
||||||
unsigned char GetRegInfo (struct CodeSeg* S, unsigned Index);
|
unsigned GetRegInfo (struct CodeSeg* S, unsigned Index);
|
||||||
/* Determine register usage information for the instructions starting at the
|
/* Determine register usage information for the instructions starting at the
|
||||||
* given index.
|
* given index.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user