diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index cdf0c193f..e5bf23f68 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1674,7 +1674,6 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptBoolTrans, 1); C += RunOptFunc (S, &DOptJumpTarget1, 1); C += RunOptFunc (S, &DOptJumpTarget2, 1); - C += RunOptFunc (S, &DOptJumpTarget3, 1); C += RunOptFunc (S, &DOptCondBranches1, 1); C += RunOptFunc (S, &DOptCondBranches2, 1); C += RunOptFunc (S, &DOptRTSJumps1, 1); @@ -1689,6 +1688,7 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptCmp9, 1); C += RunOptFunc (S, &DOptTest1, 1); C += RunOptFunc (S, &DOptLoad1, 1); + C += RunOptFunc (S, &DOptJumpTarget3, 1); /* After OptCondBranches2 */ C += RunOptFunc (S, &DOptUnusedLoads, 1); C += RunOptFunc (S, &DOptUnusedStores, 1); C += RunOptFunc (S, &DOptDupLoads, 1); diff --git a/src/cc65/coptind.c b/src/cc65/coptind.c index 81037b6fa..abb415e82 100644 --- a/src/cc65/coptind.c +++ b/src/cc65/coptind.c @@ -430,14 +430,24 @@ unsigned OptJumpCascades (CodeSeg* S) /* Get this entry */ CodeEntry* E = CS_GetEntry (S, I); - /* 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. + /* Check: + * - if it's a branch, + * - if it has a jump label, + * - if this jump label is not attached to the instruction itself, + * - if the target instruction is itself a branch, + * - if either the first branch is unconditional or the target of + * the second branch is internal to the function. + * The latter condition will avoid conditional branches to targets + * outside of the function (usually incspx), which won't simplify the + * code, since conditional far branches are emulated by a short branch + * around a jump. */ - if ((E->Info & OF_BRA) != 0 && - (OldLabel = E->JumpTo) != 0 && - (N = OldLabel->Owner) != E && - (N->Info & OF_BRA) != 0) { + if ((E->Info & OF_BRA) != 0 && + (OldLabel = E->JumpTo) != 0 && + (N = OldLabel->Owner) != E && + (N->Info & OF_BRA) != 0 && + ((E->Info & OF_CBRA) == 0 || + N->JumpTo != 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