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:
parent
a9702f8a52
commit
3c04d5777f
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user