1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-11 11:30:13 +00:00

Fixed a problem with the Chg/Use flags

git-svn-id: svn://svn.cc65.org/cc65/trunk@734 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-05-20 18:51:12 +00:00
parent a9702f8a52
commit 3c04d5777f
4 changed files with 62 additions and 87 deletions

View File

@ -133,6 +133,27 @@ static int NumArg (const char* Arg, unsigned long* Num)
static void SetUseChgInfo (CodeEntry* E, const OPCDesc* D)
/* Set the Use and Chg in E */
{
/* 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
* does not change any registers, so we don't need to use the data from D.
*/
if (E->OPC == OPC_JSR || ((E->Info & OF_BRA) != 0 && E->JumpTo == 0)) {
/* A subroutine call or jump to external symbol (function exit) */
GetFuncInfo (E->Arg, &E->Use, &E->Chg);
} else {
/* Some other instruction. Use the values from the opcode description
* plus addressing mode info
*/
E->Use = D->Use | GetAMUseInfo (E->AM);
E->Chg = D->Chg;
}
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
@ -160,19 +181,8 @@ CodeEntry* NewCodeEntry (opc_t OPC, am_t AM, const char* Arg, CodeLabel* JumpTo)
E->Flags = 0;
}
E->Info = D->Info;
E->Use = D->Use;
E->Chg = D->Chg;
if (E->OPC == OPC_JSR) {
/* A subroutine call */
GetFuncInfo (E->Arg, &E->Use, &E->Chg);
} else if ((E->Info & OF_BRA) != 0 && JumpTo == 0) {
/* Jump to external symbol (function exit) */
GetFuncInfo (E->Arg, &E->Use, &E->Chg);
} else {
/* Some other instruction */
E->Use |= GetAMUseInfo (E->AM);
}
E->JumpTo = JumpTo;
SetUseChgInfo (E, D);
InitCollection (&E->Labels);
/* If we have a label given, add this entry to the label */
@ -213,15 +223,7 @@ void ReplaceOPC (CodeEntry* E, opc_t OPC)
E->OPC = OPC;
E->Size = GetInsnSize (E->OPC, E->AM);
E->Info = D->Info;
E->Use = D->Use;
E->Chg = D->Chg;
if (E->OPC == OPC_JSR) {
/* A subroutine call */
GetFuncInfo (E->Arg, &E->Use, &E->Chg);
} else {
/* Some other instruction */
E->Use |= GetAMUseInfo (E->AM);
}
SetUseChgInfo (E, D);
}

View File

@ -127,10 +127,9 @@ static int CompareFuncInfo (const void* Key, const void* Info)
void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg)
/* For the given function, lookup register information and combine it with
* the information already in place. If the function is unknown, assume it
* will use all registers and load all registers.
* See codeinfo.h for possible flags.
/* For the given function, lookup register information and store it into
* the given variables. If the function is unknown, assume it will use and
* load all registers.
*/
{
/* Search for the function */
@ -140,12 +139,12 @@ void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg)
/* Do we know the function? */
if (Info) {
/* Use the information we have */
*Use |= Info->Use;
*Chg |= Info->Chg;
*Use = Info->Use;
*Chg = Info->Chg;
} else {
/* Assume all registers used */
*Use |= REG_AXY;
*Chg |= REG_AXY;
*Use = REG_AXY;
*Chg = REG_AXY;
}
}

View File

@ -77,9 +77,9 @@ struct CodeSeg;
void GetFuncInfo (const char* Name, unsigned char* Use, unsigned char* Chg);
/* For the given function, lookup register information and combine it with
* the information already in place. If the function is unknown, assume it
* will use all registers and load all registers.
/* For the given function, lookup register information and store it into
* the given variables. If the function is unknown, assume it will use and
* load all registers.
*/
unsigned char GetRegInfo (struct CodeSeg* S, unsigned Index);

View File

@ -217,38 +217,25 @@ unsigned OptJumpCascades (CodeSeg* S)
*/
{
unsigned Changes = 0;
unsigned I;
/* Get the number of entries, bail out if we have no entries */
unsigned Count = GetCodeEntryCount (S);
if (Count == 0) {
return 0;
}
/* Walk over all entries */
I = 0;
while (I < Count) {
unsigned I = 0;
while (I < GetCodeEntryCount (S)) {
CodeEntry* N;
CodeLabel* OldLabel;
/* Get this entry */
CodeEntry* E = GetCodeEntry (S, I);
/* Check if it's a branch, if it has a jump label, and if this jump
* label is not attached to the instruction itself.
/* Check if it's a branch, if it has a jump label, if this jump
* label is not attached to the instruction itself, and if the
* target instruction is itself a branch.
*/
if ((E->Info & OF_BRA) != 0 && E->JumpTo != 0 && E->JumpTo->Owner != E) {
/* Get the label this insn is branching to */
CodeLabel* OldLabel = E->JumpTo;
/* Get the entry we're branching to */
CodeEntry* N = OldLabel->Owner;
/* If the entry we're branching to is not itself a branch, it is
* not what we're searching for.
*/
if ((N->Info & OF_BRA) == 0) {
goto NextEntry;
}
if ((E->Info & OF_BRA) != 0 &&
(OldLabel = E->JumpTo) != 0 &&
(N = OldLabel->Owner) != E &&
(N->Info & OF_BRA) != 0) {
/* Check if we can use the final target label. This is the case,
* if the target branch is an absolut branch, or if it is a
@ -259,23 +246,15 @@ unsigned OptJumpCascades (CodeSeg* S)
GetBranchCond (E->OPC) == GetBranchCond (N->OPC))) {
/* This is a jump cascade and we may jump to the final target.
* If we have a label, move the reference to this label. If
* we don't have a label, use the argument instead.
* Insert a new instruction, then remove the old one
*/
if (N->JumpTo) {
/* Move the reference to the new insn */
MoveCodeLabelRef (S, E, N->JumpTo);
} else {
/* Remove the reference to the old label */
RemoveCodeLabelRef (S, E);
}
CodeEntry* X = NewCodeEntry (E->OPC, E->AM, N->Arg, N->JumpTo);
/* Use the new argument */
CodeEntrySetArg (E, N->Arg);
/* Insert it behind E */
InsertCodeEntry (S, X, I+1);
/* Use the usage information from the new instruction */
E->Use = N->Use;
E->Chg = N->Chg;
/* Remove E */
DelCodeEntry (S, I);
/* Remember, we had changes */
++Changes;
@ -292,7 +271,6 @@ unsigned OptJumpCascades (CodeSeg* S)
*/
if ((E->Info & OF_CBRA) != 0 && (N->Info & OF_CBRA) != 0) {
unsigned NI; /* Index of N */
CodeEntry* X; /* Instruction behind N */
CodeLabel* LX; /* Label attached to X */
@ -306,18 +284,14 @@ unsigned OptJumpCascades (CodeSeg* S)
goto NextEntry;
}
/* We may jump behind this conditional branch. This means that
* N may not be the last entry.
/* We may jump behind this conditional branch. Get the
* pointer to the next instruction
*/
NI = GetCodeEntryIndex (S, N);
if (NI >= Count-1) {
/* N is last entry */
if ((X = GetNextCodeEntry (S, GetCodeEntryIndex (S, N))) == 0) {
/* N is the last entry, bail out */
goto NextEntry;
}
/* Get the pointer to the next instruction */
X = GetCodeEntry (S, NI+1);
/* Get the label attached to X, create a new one if needed */
LX = GenCodeLabel (S, X);