From 82919fa2f8eb5baf6d859f8334271d63fd848660 Mon Sep 17 00:00:00 2001 From: uz Date: Sat, 29 Aug 2009 11:31:28 +0000 Subject: [PATCH] Another tiny code improvement for integer compares. git-svn-id: svn://svn.cc65.org/cc65/trunk@4071 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codeopt.c | 3 ++ src/cc65/coptcmp.c | 73 ++++++++++++++++++++++++++++++++++++++++++++-- src/cc65/coptcmp.h | 21 ++++++++++--- 3 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 8a8c945d0..abd5fdb63 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1097,6 +1097,7 @@ static OptFunc DOptCmp5 = { OptCmp5, "OptCmp5", 100, 0, static OptFunc DOptCmp6 = { OptCmp6, "OptCmp6", 100, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp7 = { OptCmp7, "OptCmp7", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCmp8 = { OptCmp8, "OptCmp8", 50, 0, 0, 0, 0, 0 }; +static OptFunc DOptCmp9 = { OptCmp9, "OptCmp9", 85, 0, 0, 0, 0, 0 }; static OptFunc DOptCondBranches1= { OptCondBranches1,"OptCondBranches1", 80, 0, 0, 0, 0, 0 }; static OptFunc DOptCondBranches2= { OptCondBranches2,"OptCondBranches2", 0, 0, 0, 0, 0, 0 }; static OptFunc DOptDeadCode = { OptDeadCode, "OptDeadCode", 100, 0, 0, 0, 0, 0 }; @@ -1182,6 +1183,7 @@ static OptFunc* OptFuncs[] = { &DOptCmp6, &DOptCmp7, &DOptCmp8, + &DOptCmp9, &DOptCondBranches1, &DOptCondBranches2, &DOptDeadCode, @@ -1572,6 +1574,7 @@ static unsigned RunOptGroup3 (CodeSeg* S) C += RunOptFunc (S, &DOptCmp6, 1); C += RunOptFunc (S, &DOptCmp7, 1); C += RunOptFunc (S, &DOptCmp8, 1); + C += RunOptFunc (S, &DOptCmp9, 1); C += RunOptFunc (S, &DOptTest1, 1); C += RunOptFunc (S, &DOptLoad1, 1); C += RunOptFunc (S, &DOptUnusedLoads, 1); diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 881605ecc..cd01c3b29 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -6,8 +6,8 @@ /* */ /* */ /* */ -/* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* (C) 2001-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -920,4 +920,73 @@ NextEntry: +unsigned OptCmp9 (CodeSeg* S) +/* Search for the sequence + * + * sbc xx + * bvs/bvc L + * eor #$80 + * L: asl a + * bcc/bcs somewhere + * + * If A is not used later (which should be the case), we can branch on the N + * flag instead of the carry flag and remove the asl. + */ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[5]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (L[0]->OPC == OP65_SBC && + CS_GetEntries (S, L+1, I+1, 4) && + (L[1]->OPC == OP65_BVC || + L[1]->OPC == OP65_BVS) && + L[1]->JumpTo != 0 && + L[1]->JumpTo->Owner == L[3] && + L[2]->OPC == OP65_EOR && + CE_IsKnownImm (L[2], 0x80) && + L[3]->OPC == OP65_ASL && + L[3]->AM == AM65_ACC && + (L[4]->OPC == OP65_BCC || + L[4]->OPC == OP65_BCS || + L[4]->OPC == OP65_JCC || + L[4]->OPC == OP65_JCS) && + !CE_HasLabel (L[4]) && + !RegAUsed (S, I+4)) { + + /* Replace the branch condition */ + switch (GetBranchCond (L[4]->OPC)) { + case BC_CC: CE_ReplaceOPC (L[4], OP65_JPL); break; + case BC_CS: CE_ReplaceOPC (L[4], OP65_JMI); break; + default: Internal ("Unknown branch condition in OptCmp9"); + } + + /* Delete the asl insn */ + CS_DelEntry (S, I+3); + + /* Next sequence is somewhat ahead (if any) */ + I += 3; + + /* Remember, we had changes */ + ++Changes; + } + + /* Next entry */ + ++I; + } + + /* Return the number of changes made */ + return Changes; +} + + diff --git a/src/cc65/coptcmp.h b/src/cc65/coptcmp.h index 39a79121f..7efbeada8 100644 --- a/src/cc65/coptcmp.h +++ b/src/cc65/coptcmp.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -153,6 +153,19 @@ unsigned OptCmp8 (CodeSeg* S); * the result of the compare is known. */ +unsigned OptCmp9 (CodeSeg* S); +/* Search for the sequence + * + * sbc xx + * bvs/bvc L + * eor #$80 + * L: asl a + * bcc/bcs somewhere + * + * If A is not used later (which should be the case), we can branch on the N + * flag instead of the carry flag and remove the asl. + */ + /* End of coptcmp.h */ -- 2.39.5