/*****************************************************************************/
-
+
#if 0
static unsigned OptSize1 (CodeSeg* S)
/* Do size optimization by calling special subroutines that preload registers.
static OptFunc DOptJumpCascades = { OptJumpCascades, "OptJumpCascades", 0, 0, 0, 0, 0 };
static OptFunc DOptJumpTarget = { OptJumpTarget, "OptJumpTarget", 0, 0, 0, 0, 0 };
static OptFunc DOptRTS = { OptRTS, "OptRTS", 0, 0, 0, 0, 0 };
-static OptFunc DOptRTSJumps = { OptRTSJumps, "OptRTSJumps", 0, 0, 0, 0, 0 };
+static OptFunc DOptRTSJumps1 = { OptRTSJumps1, "OptRTSJumps1", 0, 0, 0, 0, 0 };
+static OptFunc DOptRTSJumps2 = { OptRTSJumps2, "OptRTSJumps2", 0, 0, 0, 0, 0 };
static OptFunc DOptNegA1 = { OptNegA1, "OptNegA1", 0, 0, 0, 0, 0 };
static OptFunc DOptNegA2 = { OptNegA2, "OptNegA2", 0, 0, 0, 0, 0 };
static OptFunc DOptNegAX1 = { OptNegAX1, "OptNegAX1", 0, 0, 0, 0, 0 };
&DOptPtrStore1,
&DOptPtrStore2,
&DOptRTS,
- &DOptRTSJumps,
+ &DOptRTSJumps1,
+ &DOptRTSJumps2,
&DOptShift1,
&DOptShift2,
/*&DOptSize1,*/
Changes += RunOptFunc (S, &DOptDeadCode, 1);
Changes += RunOptFunc (S, &DOptJumpTarget, 1);
Changes += RunOptFunc (S, &DOptCondBranches, 1);
- Changes += RunOptFunc (S, &DOptRTSJumps, 1);
+ Changes += RunOptFunc (S, &DOptRTSJumps1, 1);
Changes += RunOptFunc (S, &DOptBoolTrans, 1);
Changes += RunOptFunc (S, &DOptCmp1, 1);
Changes += RunOptFunc (S, &DOptCmp2, 1);
*/
RunOptFunc (S, &DOptJumpTarget, 5);
- /* Finally, adjust branch distances */
+ /* Adjust branch distances */
RunOptFunc (S, &DOptBranchDist, 3);
+
+ /* Replace conditional branches to RTS. If we had changes, we must run dead
+ * code elimination again, since the change may have introduced dead code.
+ */
+ if (RunOptFunc (S, &DOptRTSJumps2, 1)) {
+ RunOptFunc (S, &DOptDeadCode, 1);
+ }
}
/*****************************************************************************/
-/* Replace jumps to RTS by RTS */
+/* Replace jumps to RTS by RTS */
/*****************************************************************************/
-unsigned OptRTSJumps (CodeSeg* S)
+unsigned OptRTSJumps1 (CodeSeg* S)
/* Replace jumps to RTS by RTS */
{
unsigned Changes = 0;
+unsigned OptRTSJumps2 (CodeSeg* S)
+/* Replace long conditional jumps to RTS */
+{
+ unsigned Changes = 0;
+
+ /* Walk over all entries minus the last one */
+ unsigned I = 0;
+ while (I < CS_GetEntryCount (S)) {
+
+ CodeEntry* N;
+
+ /* Get the next entry */
+ CodeEntry* E = CS_GetEntry (S, I);
+
+ /* Check if it's an unconditional branch to a local target */
+ if ((E->Info & OF_CBRA) != 0 && /* Conditional branch */
+ (E->Info & OF_LBRA) != 0 && /* Long branch */
+ 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 */
+ X = NewCodeEntry (OP65_RTS, AM65_IMP, 0, 0, E->JumpTo->Owner->LI);
+ CS_InsertEntry (S, X, I+1);
+
+ /* 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 */
+ ++I;
+
+ }
+
+ /* Return the number of changes made */
+ return Changes;
+}
+
+
+
/*****************************************************************************/
/* Remove dead jumps */
/*****************************************************************************/