From 0a6895ca05bd2dae0a4960617c6d14bc75d3885a Mon Sep 17 00:00:00 2001 From: cuz Date: Sat, 29 Sep 2001 20:34:31 +0000 Subject: [PATCH] Working on optimizations git-svn-id: svn://svn.cc65.org/cc65/trunk@985 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codeopt.c | 67 +++++++++++++++++++++++++++---------------- src/cc65/codeseg.c | 6 ++-- src/cc65/coptadd.c | 71 +++++++++++++++++++++++----------------------- src/cc65/coptcmp.c | 21 +++++++------- 4 files changed, 92 insertions(+), 73 deletions(-) diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 36798b78e..d249b9958 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -790,6 +790,7 @@ static unsigned OptPtrLoad1 (CodeSeg* S) static unsigned OptPtrLoad2 (CodeSeg* S) /* Search for the sequence: * + * clc * adc xxx * tay * txa @@ -801,6 +802,7 @@ static unsigned OptPtrLoad2 (CodeSeg* S) * * and replace it by: * + * clc * adc xxx * sta ptr1 * txa @@ -817,52 +819,67 @@ static unsigned OptPtrLoad2 (CodeSeg* S) unsigned I = 0; while (I < CS_GetEntryCount (S)) { - CodeEntry* L[8]; + CodeEntry* L[9]; /* Get next entry */ L[0] = CS_GetEntry (S, I); /* Check for the sequence */ - if (L[0]->OPC == OP65_ADC && - CS_GetEntries (S, L+1, I+1, 7) && - L[1]->OPC == OP65_TAY && - !CE_HasLabel (L[1]) && - L[2]->OPC == OP65_TXA && - !CE_HasLabel (L[2]) && - L[3]->OPC == OP65_ADC && + if (L[0]->OPC == OP65_CLC && + CS_GetEntries (S, L+1, I+1, 8) && + L[1]->OPC == OP65_ADC && + !CE_HasLabel (L[1]) && + L[2]->OPC == OP65_TAY && + !CE_HasLabel (L[2]) && + L[3]->OPC == OP65_TXA && !CE_HasLabel (L[3]) && - L[4]->OPC == OP65_TAX && + L[4]->OPC == OP65_ADC && !CE_HasLabel (L[4]) && - L[5]->OPC == OP65_TYA && + L[5]->OPC == OP65_TAX && !CE_HasLabel (L[5]) && - L[6]->OPC == OP65_LDY && + L[6]->OPC == OP65_TYA && !CE_HasLabel (L[6]) && - CE_IsCall (L[7], "ldauidx") && - !CE_HasLabel (L[7])) { + L[7]->OPC == OP65_LDY && + !CE_HasLabel (L[7]) && + CE_IsCall (L[8], "ldauidx") && + !CE_HasLabel (L[8])) { CodeEntry* X; + CodeEntry* P; /* Store the low byte and remove the TAY instead */ - X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[0]->LI); - CS_InsertEntry (S, X, I+1); - CS_DelEntry (S, I+2); + X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1", 0, L[1]->LI); + CS_InsertEntry (S, X, I+2); + CS_DelEntry (S, I+3); /* Store the high byte */ - X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1+1", 0, L[3]->LI); - CS_InsertEntry (S, X, I+4); + X = NewCodeEntry (OP65_STA, AM65_ZP, "ptr1+1", 0, L[4]->LI); + CS_InsertEntry (S, X, I+5); + + /* If the instruction before the adc is a ldx, replace the + * txa by and lda with the same location of the ldx. + */ + if ((P = CS_GetPrevEntry (S, I)) != 0 && + P->OPC == OP65_LDX && + !CE_HasLabel (P)) { + + X = NewCodeEntry (OP65_LDA, P->AM, P->Arg, 0, P->LI); + CS_InsertEntry (S, X, I+4); + CS_DelEntry (S, I+3); + } /* Delete more transfer insns */ + CS_DelEntry (S, I+7); CS_DelEntry (S, I+6); - CS_DelEntry (S, I+5); /* Delete the call to ldauidx */ - CS_DelEntry (S, I+6); + CS_DelEntry (S, I+7); /* Load high and low byte */ - X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[6]->LI); - CS_InsertEntry (S, X, I+6); - X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[6]->LI); + X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[7]->LI); CS_InsertEntry (S, X, I+7); + X = NewCodeEntry (OP65_LDA, AM65_ZP_INDY, "ptr1", 0, L[7]->LI); + CS_InsertEntry (S, X, I+8); /* Remember, we had changes */ ++Changes; @@ -1381,7 +1398,7 @@ static unsigned OptDecouple (CodeSeg* S) /*****************************************************************************/ -/* Size optimization */ +/* Size optimization */ /*****************************************************************************/ @@ -1424,7 +1441,7 @@ static unsigned OptSize (CodeSeg* S) X = NewCodeEntry (OP65_DEA, AM65_IMP, 0, 0, E->LI); } else if (Val == ((E->RI->In.RegA + 1) & 0xFF)) { X = NewCodeEntry (OP65_INA, AM65_IMP, 0, 0, E->LI); - } + } } } break; diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 567b2e96b..e4db1257a 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -1047,9 +1047,9 @@ void CS_GenRegInfo (CodeSeg* S) /* Generate register infos for all instructions */ { unsigned I; - RegContents Regs; - RegContents* CurrentRegs; - int WasJump; + RegContents Regs; /* Initial register contents */ + RegContents* CurrentRegs; /* Current register contents */ + int WasJump; /* True if last insn was a jump */ /* Be sure to delete all register infos */ CS_FreeRegInfo (S); diff --git a/src/cc65/coptadd.c b/src/cc65/coptadd.c index fd30a41cf..ebda0fb5d 100644 --- a/src/cc65/coptadd.c +++ b/src/cc65/coptadd.c @@ -146,25 +146,25 @@ unsigned OptAdd1 (CodeSeg* S) unsigned OptAdd2 (CodeSeg* S) /* Search for the sequence * - * ldy #xx + * ldy #yy * lda (sp),y * tax - * dey + * ldy #xx * lda (sp),y - * ldy #$yy + * ldy #zz * jsr addeqysp * * and replace it by: * - * ldy #xx-1 + * ldy #xx * lda (sp),y - * ldy #yy + * ldy #zz * clc * adc (sp),y * sta (sp),y - * ldy #xx + * ldy #yy * lda (sp),y - * ldy #yy+1 + * ldy #zz+1 * adc (sp),y * sta (sp),y * @@ -191,7 +191,8 @@ unsigned OptAdd2 (CodeSeg* S) !CE_HasLabel (L[1]) && L[2]->OPC == OP65_TAX && !CE_HasLabel (L[2]) && - L[3]->OPC == OP65_DEY && + L[3]->OPC == OP65_LDY && + CE_KnownImm (L[3]) && !CE_HasLabel (L[3]) && L[4]->OPC == OP65_LDA && L[4]->AM == AM65_ZP_INDY && @@ -207,44 +208,43 @@ unsigned OptAdd2 (CodeSeg* S) CodeEntry* X; - /* Adjust the operand of the first LDY */ - CE_SetNumArg (L[0], L[0]->Num - 1); + /* Insert new code behind the addeqysp */ + X = NewCodeEntry (OP65_LDY, AM65_IMM, L[3]->Arg, 0, L[3]->LI); + CS_InsertEntry (S, X, I+7); - /* Load Y with the low offset of the target variable */ - X = NewCodeEntry (OP65_LDY, AM65_IMM, L[5]->Arg, 0, L[1]->LI); - CS_InsertEntry (S, X, I+2); + X = NewCodeEntry (OP65_LDA, L[4]->AM, L[4]->Arg, 0, L[4]->LI); + CS_InsertEntry (S, X, I+8); - /* Add the CLC */ - X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[1]->LI); - CS_InsertEntry (S, X, I+3); + X = NewCodeEntry (OP65_LDY, AM65_IMM, L[5]->Arg, 0, L[5]->LI); + CS_InsertEntry (S, X, I+9); - /* Remove the TAX/DEY sequence */ - CS_DelEntry (S, I+5); /* dey */ - CS_DelEntry (S, I+4); /* tax */ + X = NewCodeEntry (OP65_CLC, AM65_IMP, 0, 0, L[6]->LI); + CS_InsertEntry (S, X, I+10); - /* Addition of the low byte */ - X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[4]->LI); - CS_InsertEntry (S, X, I+4); - X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[4]->LI); - CS_InsertEntry (S, X, I+5); + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[6]->LI); + CS_InsertEntry (S, X, I+11); + + X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[6]->LI); + CS_InsertEntry (S, X, I+12); - /* LDY */ - xsprintf (Buf, sizeof (Buf), "$%02X", (int) (L[0]->Num+1)); - X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[4]->LI); - CS_InsertEntry (S, X, I+6); + X = NewCodeEntry (OP65_LDY, AM65_IMM, L[0]->Arg, 0, L[0]->LI); + CS_InsertEntry (S, X, I+13); + + X = NewCodeEntry (OP65_LDA, L[1]->AM, L[1]->Arg, 0, L[1]->LI); + CS_InsertEntry (S, X, I+14); - /* Addition of the high byte */ xsprintf (Buf, sizeof (Buf), "$%02X", (int)(L[5]->Num+1)); X = NewCodeEntry (OP65_LDY, AM65_IMM, Buf, 0, L[5]->LI); - CS_InsertEntry (S, X, I+8); + CS_InsertEntry (S, X, I+15); + X = NewCodeEntry (OP65_ADC, AM65_ZP_INDY, "sp", 0, L[6]->LI); - CS_InsertEntry (S, X, I+9); + CS_InsertEntry (S, X, I+16); + X = NewCodeEntry (OP65_STA, AM65_ZP_INDY, "sp", 0, L[6]->LI); - CS_InsertEntry (S, X, I+10); + CS_InsertEntry (S, X, I+17); - /* Delete the remaining stuff */ - CS_DelEntry (S, I+12); - CS_DelEntry (S, I+11); + /* Delete the old code */ + CS_DelEntries (S, I, 7); /* Remember, we had changes */ ++Changes; @@ -314,3 +314,4 @@ unsigned OptAdd3 (CodeSeg* S) + diff --git a/src/cc65/coptcmp.c b/src/cc65/coptcmp.c index 5dbddfd31..60a033cc7 100644 --- a/src/cc65/coptcmp.c +++ b/src/cc65/coptcmp.c @@ -324,14 +324,15 @@ static int IsLocalLoad16 (CodeSeg* S, unsigned Index, /* Check for the sequence */ return (L[0]->OPC == OP65_LDY && - L[0]->AM == AM65_IMM && - (L[0]->Flags & CEF_NUMARG) != 0 && + CE_KnownImm (L[0]) && CS_GetEntries (S, L+1, Index+1, Count-1) && IsSpLoad (L[1]) && !CE_HasLabel (L[1]) && L[2]->OPC == OP65_TAX && !CE_HasLabel (L[2]) && - L[3]->OPC == OP65_DEY && + L[3]->OPC == OP65_LDY && + CE_KnownImm (L[3]) && + L[3]->Num == L[0]->Num - 1 && !CE_HasLabel (L[3]) && IsSpLoad (L[4]) && !CE_HasLabel (L[4])); @@ -404,7 +405,7 @@ unsigned OptBoolTrans (CodeSeg* S) /*****************************************************************************/ /* Optimizations for compares */ /*****************************************************************************/ - + unsigned OptCmp1 (CodeSeg* S) @@ -631,10 +632,10 @@ unsigned OptCmp4 (CodeSeg* S) if (L[5]->Num == 0 && L[7]->Num == 0) { - /* The value is zero, we may use the simple code version: - * ldy #o - * lda (sp),y - * dey + /* The value is zero, we may use the simple code version: + * ldy #o + * lda (sp),y + * ldy #o-1 * ora (sp),y * jne/jeq ... */ @@ -651,7 +652,7 @@ unsigned OptCmp4 (CodeSeg* S) * lda (sp),y * cmp #a * bne L1 - * dey + * ldy #o-1 * lda (sp),y * cmp #b * jne/jeq ... @@ -697,7 +698,7 @@ unsigned OptCmp5 (CodeSeg* S) CodeEntry* E = CS_GetEntry (S, I); /* Check for the sequence */ - if (E->OPC == OP65_JSR && + if (E->OPC == OP65_JSR && (Cond = FindTosCmpCond (E->Arg)) != CMP_INV && (N = CS_GetNextEntry (S, I)) != 0 && (N->Info & OF_ZBRA) != 0 && -- 2.39.5