- CS_InsertEntry (S, X, I+1);
- CS_DelEntry (S, I);
- ++Changes;
- }
-
- /* Next entry */
- ++I;
-
- }
-
- /* Free register info */
- CS_FreeRegInfo (S);
-
- /* Return the number of changes made */
- return Changes;
-}
-
-
-
-/*****************************************************************************/
-/* Size optimization */
-/*****************************************************************************/
-
-
-
-#if 0
-static unsigned OptSize1 (CodeSeg* S)
-/* Do size optimization by calling special subroutines that preload registers.
- * This routine does not work standalone, it needs a following register load
- * removal pass.
- */
-{
- static const char* Func = {
- "stax0sp", /* staxysp, y = 0 */
- "addeq0sp",
- "ldax0sp", /* ldaxysp, y = 1 */
- "ldeax0sp", /* ldeaxysp, y = 3 */
- "push0", /* pushax, a = 0, x = 0 */
- "pusha0", /* pushax, x = 0 */
- "pushaFF", /* pushax, x = ff */
- "pusha0sp", /* pushaysp, y = 0 */
- "tosadda0", /* tosaddax, x = 0 */
- "tosanda0", /* tosandax, x = 0 */
- "tosdiva0", /* tosdivax, x = 0 */
- "toseqa0", /* toseqax, x = 0 */
- "tosgea0", /* tosgeax, x = 0 */
- "tosgta0", /* tosgtax, x = 0 */
- "tosadd0ax", /* tosaddeax, sreg = 0 */
- "laddeqa", /* laddeq, sreg = 0, x = 0 */
- "laddeq1", /* laddeq, sreg = 0, x = 0, a = 1 */
- "laddeq0sp", /* laddeqysp, y = 0 */
- "tosand0ax", /* tosandeax, sreg = 0 */
- "ldaxi", /* ldaxidx, y = 1 */
- "ldeaxi", /* ldeaxidx, y = 3 */
- "ldeax0sp", /* ldeaxysp, y = 3 */
- "tosdiv0ax", /* tosdiveax, sreg = 0 */
- "toslea0", /* tosleax, x = 0 */
- "tosmod0ax", /* tosmodeax, sreg = 0 */
- "tosmul0ax", /* tosmuleax, sreg = 0 */
- "tosumul0ax", /* tosumuleax, sreg = 0 */
- "tosor0ax", /* tosoreax, sreg = 0 */
- "push0ax", /* pusheax, sreg = 0 */
- "tosrsub0ax", /* tosrsubeax, sreg = 0 */
- "tosshl0ax", /* tosshleax, sreg = 0 */
- "tosasl0ax", /* tosasleax, sreg = 0 */
- "tosshr0ax", /* tosshreax, sreg = 0 */
- "tosasr0ax", /* tosasreax, sreg = 0 */
- "tossub0ax", /* tossubeax, sreg = 0 */
- "lsubeqa", /* lsubeq, sreg = 0, x = 0 */
- "lsubeq1", /* lsubeq, sreg = 0, x = 0, a = 1 */
- "lsubeq0sp", /* lsubeqysp, y = 0 */
- "toslta0", /* tosltax, x = 0 */
- "tosudiv0ax", /* tosudiveax, sreg = 0 */
- "tosumod0ax", /* tosumodeax, sreg = 0 */
- "tosxor0ax", /* tosxoreax, sreg = 0 */
- "tosmoda0", /* tosmodax, x = 0 */
- "tosmula0", /* tosmulax, x = 0 */
- "tosumula0", /* tosumulax, x = 0 */
- "tosnea0", /* tosneax, x = 0 */
- "tosora0", /* tosorax, x = 0 */
- "push1", /* pushax, x = 0, a = 1 */
- "push2", /* pushax, x = 0, a = 2 */
- "push3", /* pushax, x = 0, a = 3 */
- "push4", /* pushax, x = 0, a = 4 */
- "push5", /* pushax, x = 0, a = 5 */
- "push6", /* pushax, x = 0, a = 6 */
- "push7", /* pushax, x = 0, a = 7 */
- "pushc0", /* pusha, a = 0 */
- "pushc1", /* pusha, a = 1 */
- "pushc2", /* pusha, a = 2 */
- "tosrsuba0", /* tosrsubax, x = 0 */
- "tosshla0", /* tosshlax, x = 0 */
- "tosasla0", /* tosaslax, x = 0 */
- "tosshra0", /* tosshrax, x = 0 */
- "tosasra0", /* tosasrax, x = 0 */
- "steax0sp", /* steaxsp, y = 0 */
- "tossuba0", /* tossubax, x = 0 */
- "subeq0sp", /* subeqysp, y = 0 */
- "tosudiva0", /* tosudivax, x = 0 */
- "tosugea0", /* tosugeax, x = 0 */
- "tosugta0", /* tosugtax, x = 0 */
- "tosulea0", /* tosuleax, x = 0 */
- "tosulta0", /* tosultax, x = 0 */
- "tosumoda0", /* tosumodax, x = 0 */
- "tosxora0", /* tosxorax, x = 0 */
- };
-
- unsigned Changes = 0;
- unsigned I;
-
- /* Generate register info for the following step */
- CS_GenRegInfo (S);
-
- /* Walk over the entries */
- I = 0;
- while (I < CS_GetEntryCount (S)) {
-
- /* Get next entry */
- CodeEntry* E = CS_GetEntry (S, I);
-
-
- /* Next entry */
- ++I;
-
- }
-
- /* Free register info */
- CS_FreeRegInfo (S);
-
- /* Return the number of changes made */
- return Changes;
-}
-#endif
-
-
-
-static unsigned OptSize2 (CodeSeg* S)
-/* Do size optimization by using shorter code sequences, even if this
- * introduces relations between instructions. This step must be one of the
- * last steps, because it makes further work much more difficult.
- */
-{
- unsigned Changes = 0;
- unsigned I;
-
- /* Generate register info for the following step */
- CS_GenRegInfo (S);
-
- /* Walk over the entries */
- I = 0;
- while (I < CS_GetEntryCount (S)) {
-
-
- /* Get next entry */
- CodeEntry* E = CS_GetEntry (S, I);
-
- /* Assume we have no replacement */
- CodeEntry* X = 0;
-
- /* Check the instruction */
- switch (E->OPC) {
-
- case OP65_LDA:
- if (CE_KnownImm (E)) {
- short Val = (short) E->Num;
- if (Val == E->RI->In.RegX) {
- X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI);
- } else if (Val == E->RI->In.RegY) {
- X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI);
- } else if (E->RI->In.RegA >= 0 && CPU >= CPU_65C02) {
- if (Val == ((E->RI->In.RegA - 1) & 0xFF)) {
- 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;
-
- case OP65_LDX:
- if (CE_KnownImm (E)) {
- short Val = (short) E->Num;
- if (E->RI->In.RegX >= 0 && Val == ((E->RI->In.RegX - 1) & 0xFF)) {
- X = NewCodeEntry (OP65_DEX, AM65_IMP, 0, 0, E->LI);
- } else if (E->RI->In.RegX >= 0 && Val == ((E->RI->In.RegX + 1) & 0xFF)) {
- X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, E->LI);
- } else if (Val == E->RI->In.RegA) {
- X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI);
- }
- }
- break;
-
- case OP65_LDY:
- if (CE_KnownImm (E)) {
- short Val = (short) E->Num;
- if (E->RI->In.RegY >= 0 && Val == ((E->RI->In.RegY - 1) & 0xFF)) {
- X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, E->LI);
- } else if (E->RI->In.RegY >= 0 && Val == ((E->RI->In.RegY + 1) & 0xFF)) {
- X = NewCodeEntry (OP65_INY, AM65_IMP, 0, 0, E->LI);
- } else if (Val == E->RI->In.RegA) {
- X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI);
- }
- }
- break;
-
- default:
- /* Avoid gcc warnings */
- break;
-
- }
-
- /* Insert the replacement if we have one */
- if (X) {
- CS_InsertEntry (S, X, I+1);