X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcoptptrload.c;h=c508d56f492b67d6147736b69fb998df3b0903f7;hb=5d274e4bc5b81002146e72602dae235dcd4c591e;hp=ee783c93f3ad3fd58f88660a14ea751f8e10e697;hpb=0b186407f1117529f0f6902569f9d24bc8b1b979;p=cc65 diff --git a/src/cc65/coptptrload.c b/src/cc65/coptptrload.c index ee783c93f..c508d56f4 100644 --- a/src/cc65/coptptrload.c +++ b/src/cc65/coptptrload.c @@ -1457,3 +1457,213 @@ unsigned OptPtrLoad17 (CodeSeg* S) /* Return the number of changes made */ return Changes; } + + + +unsigned OptPtrLoad18 (CodeSeg* S) +/* Search for the sequence: +** +** ldx #$xx +** lda #$yy +** clc +** adc xxx +** bcc L +** inx +** L: ldy #$00 +** jsr ldauidx +** +** and replace it by: +** +** ldy xxx +** ldx #$00 +** lda $xxyy,y +** +** This is similar to OptPtrLoad3 but works on a constant address +** instead of a label. Also, the initial X and A loads are reversed. +** Must be run before OptPtrLoad11. +*/ +{ + unsigned Changes = 0; + + /* Walk over the entries */ + unsigned I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[8]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (L[0]->OPC == OP65_LDX && + L[0]->AM == AM65_IMM && + CS_GetEntries (S, L+1, I+1, 7) && + L[1]->OPC == OP65_LDA && + L[1]->AM == AM65_IMM && + L[2]->OPC == OP65_CLC && + L[3]->OPC == OP65_ADC && + (L[3]->AM == AM65_ABS || L[3]->AM == AM65_ZP) && + (L[4]->OPC == OP65_BCC || L[4]->OPC == OP65_JCC) && + L[4]->JumpTo != 0 && + L[4]->JumpTo->Owner == L[6] && + L[5]->OPC == OP65_INX && + L[6]->OPC == OP65_LDY && + CE_IsKnownImm (L[6], 0) && + CE_IsCallTo (L[7], "ldauidx") && + !CS_RangeHasLabel (S, I+1, 5) && + !CE_HasLabel (L[7]) && + strlen (L[0]->Arg) == 3 && + L[0]->Arg[0] == '$' && + strlen (L[1]->Arg) == 3 && + L[1]->Arg[0] == '$' ) { + + CodeEntry* X; + char* Label; + + /* We will create all the new stuff behind the current one so + ** we keep the line references. + */ + X = NewCodeEntry (OP65_LDY, L[3]->AM, L[3]->Arg, 0, L[0]->LI); + CS_InsertEntry (S, X, I+8); + + X = NewCodeEntry (OP65_LDX, AM65_IMM, "$00", 0, L[0]->LI); + CS_InsertEntry (S, X, I+9); + + Label = xmalloc(6); + sprintf(Label, "$%s%s", L[0]->Arg+1, L[1]->Arg+1); + X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[0]->LI); + CS_InsertEntry (S, X, I+10); + xfree (Label); + + /* Remove the old code */ + CS_DelEntries (S, I, 8); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + + +unsigned OptPtrLoad19 (CodeSeg* S) +/* Search for the sequence: +** +** and #mask (any value < 128) +** jsr aslax1/shlax1 +** clc +** adc #<(label+0) +** tay +** txa +** adc #>(label+0) +** tax +** tya +** ldy #$01 +** jsr ldaxidx +** +** and replace it by: +** +** and #mask (remove if == 127) +** asl +** tay +** lda label,y +** ldx label+1,y +*/ +{ + unsigned Changes = 0; + unsigned I; + + /* Walk over the entries */ + I = 0; + while (I < CS_GetEntryCount (S)) { + + CodeEntry* L[11]; + + /* Get next entry */ + L[0] = CS_GetEntry (S, I); + + /* Check for the sequence */ + if (L[0]->OPC == OP65_AND && + L[0]->AM == AM65_IMM && + CE_HasNumArg (L[0]) && L[0]->Num <= 127 && + CS_GetEntries (S, L+1, I+1, 10) && + L[1]->OPC == OP65_JSR && + (strcmp (L[1]->Arg, "aslax1") == 0 || + strcmp (L[1]->Arg, "shlax1") == 0) && + L[2]->OPC == OP65_CLC && + L[3]->OPC == OP65_ADC && + L[4]->OPC == OP65_TAY && + L[5]->OPC == OP65_TXA && + L[6]->OPC == OP65_ADC && + L[7]->OPC == OP65_TAX && + L[8]->OPC == OP65_TYA && + L[9]->OPC == OP65_LDY && + CE_IsKnownImm(L[9], 1) && + strlen(L[3]->Arg) >= 3 && + L[3]->Arg[0] == '<' && + strlen(L[6]->Arg) >= 3 && + L[6]->Arg[0] == '>' && + !strcmp(L[3]->Arg+1, L[6]->Arg+1) && + CE_IsCallTo (L[10], "ldaxidx") && + !CS_RangeHasLabel (S, I+1, 10)) { + + CodeEntry* X; + char* Label; + int Len = strlen(L[3]->Arg); + + /* Track the insertion point */ + unsigned IP = I + 11; + + /* asl a */ + X = NewCodeEntry (OP65_ASL, AM65_ACC, "a", 0, L[1]->LI); + CS_InsertEntry (S, X, IP++); + + /* tay */ + X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, L[1]->LI); + CS_InsertEntry (S, X, IP++); + + /* lda label,y */ + Label = memcpy (xmalloc (Len-2), L[3]->Arg+2, Len-3); + Label[Len-3] = '\0'; + X = NewCodeEntry (OP65_LDA, AM65_ABSY, Label, 0, L[9]->LI); + CS_InsertEntry (S, X, IP++); + xfree (Label); + + /* lda label+1,y */ + Label = memcpy (xmalloc (Len), L[3]->Arg+2, Len-3); + strcpy(&Label[Len-3], "+1"); + X = NewCodeEntry (OP65_LDX, AM65_ABSY, Label, 0, L[9]->LI); + CS_InsertEntry (S, X, IP++); + xfree (Label); + + /* Remove the old code */ + /* Remove the AND only if it's == 127, since ASL erases high bit */ + if (L[0]->Num == 127) + CS_DelEntries (S, I, 11); + else + CS_DelEntries (S, I+1, 10); + + /* Remember, we had changes */ + ++Changes; + + } + + /* Next entry */ + ++I; + + } + + /* Return the number of changes made */ + return Changes; +} + + +