mirror of
https://github.com/cc65/cc65.git
synced 2025-02-25 16:29:08 +00:00
Working
git-svn-id: svn://svn.cc65.org/cc65/trunk@731 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
4e645d3ab8
commit
68c0d38dfa
@ -127,94 +127,118 @@ static unsigned OptBoolTransforms (CodeSeg* S)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned Changes = 0;
|
unsigned Changes = 0;
|
||||||
unsigned I;
|
|
||||||
|
|
||||||
/* Get the number of entries, bail out if we have not enough */
|
|
||||||
unsigned Count = GetCodeEntryCount (S);
|
|
||||||
if (Count < 2) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Walk over the entries */
|
/* Walk over the entries */
|
||||||
I = 0;
|
unsigned I = 0;
|
||||||
while (I < Count-1) {
|
while (I < GetCodeEntryCount (S)) {
|
||||||
|
|
||||||
|
CodeEntry* N;
|
||||||
|
cmp_t Cond;
|
||||||
|
|
||||||
/* Get next entry */
|
/* Get next entry */
|
||||||
CodeEntry* E = GetCodeEntry (S, I);
|
CodeEntry* E = GetCodeEntry (S, I);
|
||||||
|
|
||||||
/* Check for a boolean transformer */
|
/* Check for a boolean transformer */
|
||||||
if (E->OPC == OPC_JSR && strncmp (E->Arg, "bool", 4) == 0) {
|
if (E->OPC == OPC_JSR &&
|
||||||
|
strncmp (E->Arg, "bool", 4) == 0 &&
|
||||||
|
(N = GetNextCodeEntry (S, I)) != 0 &&
|
||||||
|
(N->Info & OF_ZBRA) != 0 &&
|
||||||
|
(Cond = FindCmpCond (E->Arg+4)) != CMP_INV) {
|
||||||
|
|
||||||
cmp_t Cond;
|
CodeEntry* X;
|
||||||
|
CodeLabel* L;
|
||||||
/* Get the next entry */
|
|
||||||
CodeEntry* N = GetCodeEntry (S, I+1);
|
|
||||||
|
|
||||||
/* Check if this is a conditional branch */
|
|
||||||
if ((N->Info & OF_CBRA) == 0) {
|
|
||||||
/* No conditional branch, bail out */
|
|
||||||
goto NextEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make the boolean transformer unnecessary by changing the
|
/* Make the boolean transformer unnecessary by changing the
|
||||||
* the conditional jump to evaluate the condition flags that
|
* the conditional jump to evaluate the condition flags that
|
||||||
* are set after the compare directly. Note: jeq jumps if
|
* are set after the compare directly. Note: jeq jumps if
|
||||||
* the condition is not met, jne jumps if the condition is met.
|
* the condition is not met, jne jumps if the condition is met.
|
||||||
|
* Invert the code if we jump on condition not met.
|
||||||
*/
|
*/
|
||||||
Cond = FindCmpCond (E->Arg + 4);
|
|
||||||
if (Cond == CMP_INV) {
|
|
||||||
/* Unknown function */
|
|
||||||
goto NextEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Invert the code if we jump on condition not met. */
|
|
||||||
if (GetBranchCond (N->OPC) == BC_EQ) {
|
if (GetBranchCond (N->OPC) == BC_EQ) {
|
||||||
/* Jumps if condition false, invert condition */
|
/* Jumps if condition false, invert condition */
|
||||||
Cond = CmpInvertTab [Cond];
|
Cond = CmpInvertTab [Cond];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we can replace the code by something better */
|
/* Check if we can replace the code by something better */
|
||||||
switch (Cond) {
|
switch (Cond) {
|
||||||
|
|
||||||
case CMP_EQ:
|
case CMP_EQ:
|
||||||
ReplaceOPC (N, OPC_JEQ);
|
ReplaceOPC (N, OPC_JEQ);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMP_NE:
|
case CMP_NE:
|
||||||
ReplaceOPC (N, OPC_JNE);
|
ReplaceOPC (N, OPC_JNE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMP_GT:
|
case CMP_GT:
|
||||||
/* Not now ### */
|
/* Replace by
|
||||||
goto NextEntry;
|
* beq @L
|
||||||
|
* jpl Target
|
||||||
|
* @L: ...
|
||||||
|
*/
|
||||||
|
if ((X = GetNextCodeEntry (S, I+1)) == 0) {
|
||||||
|
/* No such entry */
|
||||||
|
goto NextEntry;
|
||||||
|
}
|
||||||
|
L = GenCodeLabel (S, X);
|
||||||
|
X = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L);
|
||||||
|
InsertCodeEntry (S, X, I+1);
|
||||||
|
ReplaceOPC (N, OPC_JPL);
|
||||||
|
break;
|
||||||
|
|
||||||
case CMP_GE:
|
case CMP_GE:
|
||||||
ReplaceOPC (N, OPC_JPL);
|
ReplaceOPC (N, OPC_JPL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMP_LT:
|
case CMP_LT:
|
||||||
|
ReplaceOPC (N, OPC_JMI);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMP_LE:
|
||||||
|
/* Replace by
|
||||||
|
* jmi Target
|
||||||
|
* jeq Target
|
||||||
|
*/
|
||||||
ReplaceOPC (N, OPC_JMI);
|
ReplaceOPC (N, OPC_JMI);
|
||||||
break;
|
L = N->JumpTo;
|
||||||
|
X = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L);
|
||||||
|
InsertCodeEntry (S, X, I+2);
|
||||||
|
break;
|
||||||
|
|
||||||
case CMP_LE:
|
case CMP_UGT:
|
||||||
/* Not now ### */
|
/* Replace by
|
||||||
goto NextEntry;
|
* beq @L
|
||||||
|
* jcs Target
|
||||||
case CMP_UGT:
|
* @L: ...
|
||||||
/* Not now ### */
|
*/
|
||||||
goto NextEntry;
|
if ((X = GetNextCodeEntry (S, I+1)) == 0) {
|
||||||
|
/* No such entry */
|
||||||
case CMP_UGE:
|
goto NextEntry;
|
||||||
|
}
|
||||||
|
L = GenCodeLabel (S, X);
|
||||||
|
X = NewCodeEntry (OPC_BEQ, AM_BRA, L->Name, L);
|
||||||
|
InsertCodeEntry (S, X, I+1);
|
||||||
ReplaceOPC (N, OPC_JCS);
|
ReplaceOPC (N, OPC_JCS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMP_ULT:
|
case CMP_UGE:
|
||||||
|
ReplaceOPC (N, OPC_JCS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMP_ULT:
|
||||||
|
ReplaceOPC (N, OPC_JCC);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMP_ULE:
|
||||||
|
/* Replace by
|
||||||
|
* jcc Target
|
||||||
|
* jeq Target
|
||||||
|
*/
|
||||||
ReplaceOPC (N, OPC_JCC);
|
ReplaceOPC (N, OPC_JCC);
|
||||||
break;
|
L = N->JumpTo;
|
||||||
|
X = NewCodeEntry (OPC_JEQ, AM_BRA, L->Name, L);
|
||||||
case CMP_ULE:
|
InsertCodeEntry (S, X, I+2);
|
||||||
/* Not now ### */
|
break;
|
||||||
goto NextEntry;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("Unknown jump condition: %d", Cond);
|
Internal ("Unknown jump condition: %d", Cond);
|
||||||
@ -223,7 +247,6 @@ static unsigned OptBoolTransforms (CodeSeg* S)
|
|||||||
|
|
||||||
/* Remove the call to the bool transformer */
|
/* Remove the call to the bool transformer */
|
||||||
DelCodeEntry (S, I);
|
DelCodeEntry (S, I);
|
||||||
--Count;
|
|
||||||
|
|
||||||
/* Remember, we had changes */
|
/* Remember, we had changes */
|
||||||
++Changes;
|
++Changes;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user