1 /*****************************************************************************/
5 /* Size optimizations */
9 /* (C) 2002-2009, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
49 /*****************************************************************************/
51 /*****************************************************************************/
55 /* Flags for CallDesc */
56 #define F_NONE 0x0000U /* No extra flags */
57 #define F_SLOWER 0x0001U /* Function call is slower */
59 typedef struct CallDesc CallDesc;
61 const char* LongFunc; /* Long function name */
62 RegContents Regs; /* Register contents */
63 unsigned Flags; /* Flags from above */
64 const char* ShortFunc; /* Short function name */
67 /* Note: The table is sorted. If there is more than one entry with the same
68 * name, entries are sorted best match first, so when searching linear for
69 * a match, the first one can be used because it is also the best one (or
70 * at least none of the following ones are better).
71 * Note^2: Ptr1 and Tmp1 aren't evaluated, because runtime routines don't
72 * expect parameters here.
74 static const CallDesc CallTable [] = {
75 /* Name A register X register Y register flags replacement */
80 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL,
81 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
82 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
90 1, 0, UNKNOWN_REGVAL, 0,
91 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
92 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
100 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, 0,
101 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
102 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
110 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL,
111 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
112 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
120 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL,
121 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
122 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
130 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL,
131 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
132 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
140 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL,
141 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
142 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
150 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL,
151 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
152 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
160 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
161 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
162 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
170 1, 0, UNKNOWN_REGVAL, 0,
171 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
172 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
180 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, 0,
181 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
182 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
190 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL,
191 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
192 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
200 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
201 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
202 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
210 1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
211 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
212 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
220 2, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
221 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
222 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
230 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
231 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
232 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
240 1, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
241 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
242 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
250 2, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
251 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
252 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
260 3, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
261 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
262 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
270 4, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
271 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
272 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
280 5, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
281 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
282 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
290 6, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
291 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
292 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
300 7, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
301 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
302 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
310 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
311 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
312 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
320 UNKNOWN_REGVAL, 0xFF, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
321 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
322 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
330 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL,
331 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
332 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
340 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
341 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
342 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
350 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, UNKNOWN_REGVAL,
351 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
352 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
360 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, UNKNOWN_REGVAL,
361 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
362 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
370 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL,
371 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
372 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
380 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL,
381 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
382 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
390 UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL,
391 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
392 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
400 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
401 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
402 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
410 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
411 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
412 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
420 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
421 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
422 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
430 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
431 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
432 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
440 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
441 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
442 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
450 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
451 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
452 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
460 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
461 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
462 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
470 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
471 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
472 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
480 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
481 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
482 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
490 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
491 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
492 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
500 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
501 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
502 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
510 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
511 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
512 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
520 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
521 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
522 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
530 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
531 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
532 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
540 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
541 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
542 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
550 0, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
551 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
552 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
560 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
561 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
562 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
570 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
571 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
572 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
580 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
581 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
582 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
590 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
591 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
592 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
600 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
601 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
602 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
610 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
611 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
612 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
620 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
621 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
622 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
630 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
631 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
632 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
640 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
641 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
642 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
650 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
651 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
652 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
660 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
661 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
662 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
670 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
671 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
672 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
680 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
681 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
682 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
690 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
691 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
692 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
700 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
701 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
702 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
710 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
711 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
712 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
720 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
721 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
722 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
730 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
731 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
732 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
740 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
741 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
742 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
750 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
751 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
752 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
760 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
761 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
762 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
770 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
771 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
772 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
780 UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
781 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
782 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
790 UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0,
791 /* SRegHi Ptr1Lo Ptr1Hi Tmp1 */
792 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
799 #define CALL_COUNT (sizeof(CallTable) / sizeof(CallTable[0]))
803 /*****************************************************************************/
805 /*****************************************************************************/
809 static const CallDesc* FindCall (const char* Name)
810 /* Find the function with the given name. Return a pointer to the table entry
811 * or NULL if the function was not found.
814 /* Do a binary search */
816 int Last = CALL_COUNT - 1;
819 while (First <= Last) {
821 /* Set current to mid of range */
822 int Current = (Last + First) / 2;
825 int Result = strcmp (CallTable[Current].LongFunc, Name);
831 /* Found. Repeat the procedure until the first of all entries
832 * with the same name is found.
839 /* Return the first entry if found, or NULL otherwise */
840 return Found? &CallTable[First] : 0;
845 static int RegMatch (short Expected, short Actual)
846 /* Check for a register match. If Expected has a value, it must be identical
850 return RegValIsUnknown (Expected) || (Expected == Actual);
855 /*****************************************************************************/
857 /*****************************************************************************/
861 unsigned OptSize1 (CodeSeg* S)
862 /* Do size optimization by calling special subroutines that preload registers.
863 * This routine does not work standalone, it needs a following register load
868 unsigned Changes = 0;
871 /* Are we optimizing for size */
872 int OptForSize = (S->CodeSizeFactor < 100);
874 /* Generate register info for the following step */
877 /* Walk over the entries */
879 while (I < CS_GetEntryCount (S)) {
884 E = CS_GetEntry (S, I);
886 /* Check if it's a subroutine call */
887 if (E->OPC == OP65_JSR && (D = FindCall (E->Arg)) != 0) {
889 /* Get input register info for this insn */
890 const RegContents* In = &E->RI->In;
892 /* FindCall finds the first entry that matches our function name.
893 * The names are listed in "best match" order, so search for the
894 * first one, that fulfills our conditions.
898 /* Check the registers and allow slower code only if
899 * optimizing for size.
901 if ((OptForSize || (D->Flags & F_SLOWER) == 0) &&
902 RegMatch (D->Regs.RegA, In->RegA) &&
903 RegMatch (D->Regs.RegX, In->RegX) &&
904 RegMatch (D->Regs.RegY, In->RegY) &&
905 RegMatch (D->Regs.SRegLo, In->SRegLo) &&
906 RegMatch (D->Regs.SRegHi, In->SRegHi)) {
908 /* Ok, match for all conditions */
910 X = NewCodeEntry (E->OPC, E->AM, D->ShortFunc, 0, E->LI);
911 CS_InsertEntry (S, X, I+1);
914 /* Remember that we had changes */
921 /* Next table entry, bail out if next entry not valid */
922 if (++D >= CallTable + CALL_COUNT ||
923 strcmp (D->LongFunc, E->Arg) != 0) {
924 /* End of table or entries reached */
935 /* Free register info */
938 /* Return the number of changes made */
944 unsigned OptSize2 (CodeSeg* S)
945 /* Do size optimization by using shorter code sequences, even if this
946 * introduces relations between instructions. This step must be one of the
947 * last steps, because it makes further work much more difficult.
950 unsigned Changes = 0;
953 /* Generate register info for the following step */
956 /* Walk over the entries */
958 while (I < CS_GetEntryCount (S)) {
961 CodeEntry* E = CS_GetEntry (S, I);
963 /* Get the input registers */
964 const RegContents* In = &E->RI->In;
966 /* Assume we have no replacement */
969 /* Check the instruction */
973 if (CE_IsConstImm (E)) {
974 short Val = (short) E->Num;
975 if (Val == In->RegX) {
976 X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI);
977 } else if (Val == In->RegY) {
978 X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI);
979 } else if (RegValIsKnown (In->RegA) && (CPUIsets[CPU] & CPU_ISET_65SC02) != 0) {
980 if (Val == ((In->RegA - 1) & 0xFF)) {
981 X = NewCodeEntry (OP65_DEA, AM65_IMP, 0, 0, E->LI);
982 } else if (Val == ((In->RegA + 1) & 0xFF)) {
983 X = NewCodeEntry (OP65_INA, AM65_IMP, 0, 0, E->LI);
990 if (CE_IsConstImm (E)) {
991 short Val = (short) E->Num;
992 if (RegValIsKnown (In->RegX) && Val == ((In->RegX - 1) & 0xFF)) {
993 X = NewCodeEntry (OP65_DEX, AM65_IMP, 0, 0, E->LI);
994 } else if (RegValIsKnown (In->RegX) && Val == ((In->RegX + 1) & 0xFF)) {
995 X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, E->LI);
996 } else if (Val == In->RegA) {
997 X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI);
1003 if (CE_IsConstImm (E)) {
1004 short Val = (short) E->Num;
1005 if (RegValIsKnown (In->RegY) && Val == ((In->RegY - 1) & 0xFF)) {
1006 X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, E->LI);
1007 } else if (RegValIsKnown (In->RegY) && Val == ((In->RegY + 1) & 0xFF)) {
1008 X = NewCodeEntry (OP65_INY, AM65_IMP, 0, 0, E->LI);
1009 } else if (Val == In->RegA) {
1010 X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI);
1016 /* Avoid gcc warnings */
1021 /* Insert the replacement if we have one */
1023 CS_InsertEntry (S, X, I+1);
1033 /* Free register info */
1036 /* Return the number of changes made */