Extend handling for "long branch to RTS" to "long branch to jump leaving

function".


git-svn-id: svn://svn.cc65.org/cc65/trunk@4368 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz
2009-10-15 11:11:20 +00:00
parent 635fae97fb
commit 1f489fd9e1

View File

@@ -247,50 +247,77 @@ unsigned OptRTSJumps1 (CodeSeg* S)
unsigned OptRTSJumps2 (CodeSeg* S) unsigned OptRTSJumps2 (CodeSeg* S)
/* Replace long conditional jumps to RTS */ /* Replace long conditional jumps to RTS or to a final target */
{ {
unsigned Changes = 0; unsigned Changes = 0;
/* Walk over all entries minus the last one */ /* Walk over all entries minus the last one */
unsigned I = 0; unsigned I = 0;
while (I < CS_GetEntryCount (S)) { while (I < CS_GetEntryCount (S) - 1) {
CodeEntry* N;
/* Get the next entry */ /* Get the next entry */
CodeEntry* E = CS_GetEntry (S, I); CodeEntry* E = CS_GetEntry (S, I);
/* Check if it's an unconditional branch to a local target */ /* Check if it's an conditional branch to a local target */
if ((E->Info & OF_CBRA) != 0 && /* Conditional branch */ if ((E->Info & OF_CBRA) != 0 && /* Conditional branch */
(E->Info & OF_LBRA) != 0 && /* Long branch */ (E->Info & OF_LBRA) != 0 && /* Long branch */
E->JumpTo != 0 && /* Local label */ E->JumpTo != 0) { /* Local label */
E->JumpTo->Owner->OPC == OP65_RTS && /* Target is an RTS */
(N = CS_GetNextEntry (S, I)) != 0) { /* There is a next entry */
CodeEntry* X;
CodeLabel* LN;
opc_t NewBranch;
/* We will create a jump around an RTS instead of the long branch */ /* Get the jump target and the next entry. There's always a next
X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->JumpTo->Owner->LI); * entry, because we don't cover the last entry in the loop.
CS_InsertEntry (S, X, I+1); */
CodeEntry* X = 0;
CodeEntry* T = E->JumpTo->Owner;
CodeEntry* N = CS_GetNextEntry (S, I);
/* Get the new branch opcode */ /* Check if it's a jump to an RTS insn */
NewBranch = MakeShortBranch (GetInverseBranch (E->OPC)); if (T->OPC == OP65_RTS) {
/* Get the label attached to N, create a new one if needed */ /* It's a jump to RTS. Create a conditional branch around an
LN = CS_GenLabel (S, N); * RTS insn.
*/
X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, T->LI);
/* Generate the branch */ } else if (T->OPC == OP65_JMP && T->JumpTo == 0) {
X = NewCodeEntry (NewBranch, AM65_BRA, LN->Name, LN, E->LI);
CS_InsertEntry (S, X, I+1);
/* Delete the long branch */ /* It's a jump to a label outside the function. Create a
CS_DelEntry (S, I); * conditional branch around a jump to the external label.
*/
X = NewCodeEntry (OP65_JMP, AM65_ABS, T->Arg, T->JumpTo, T->LI);
/* Remember, we had changes */ }
++Changes;
/* If we have a replacement insn, insert it */
if (X) {
CodeLabel* LN;
opc_t NewBranch;
/* Insert the new insn */
CS_InsertEntry (S, X, I+1);
/* Create a conditional branch with the inverse condition
* around the replacement insn
*/
/* Get the new branch opcode */
NewBranch = MakeShortBranch (GetInverseBranch (E->OPC));
/* Get the label attached to N, create a new one if needed */
LN = CS_GenLabel (S, N);
/* Generate the branch */
X = NewCodeEntry (NewBranch, AM65_BRA, LN->Name, LN, E->LI);
CS_InsertEntry (S, X, I+1);
/* Delete the long branch */
CS_DelEntry (S, I);
/* Remember, we had changes */
++Changes;
}
} }
/* Next entry */ /* Next entry */
@@ -447,7 +474,7 @@ unsigned OptJumpCascades (CodeSeg* S)
(N = OldLabel->Owner) != E && (N = OldLabel->Owner) != E &&
(N->Info & OF_BRA) != 0 && (N->Info & OF_BRA) != 0 &&
((E->Info & OF_CBRA) == 0 || ((E->Info & OF_CBRA) == 0 ||
N->JumpTo != 0)) { N->JumpTo != 0)) {
/* Check if we can use the final target label. This is the case, /* 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 * if the target branch is an absolut branch, or if it is a