]> git.sur5r.net Git - cc65/blobdiff - src/cc65/coptsize.c
Adjusted doc to code.
[cc65] / src / cc65 / coptsize.c
index 3eaf48dce23fb082efb435e24590d6abcf88067e..5c23e637cc94a853acb2cde5924511f4d0e85851 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                coptsize.c                                */
+/*                                 coptsize.c                                */
 /*                                                                           */
 /*                              Size optimizations                           */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2002      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2002-2012, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 #include <stdlib.h>
 
+/* common */
+#include "cpu.h"
+
 /* cc65 */
 #include "codeent.h"
 #include "codeinfo.h"
-#include "cpu.h"
 #include "coptsize.h"
+#include "reginfo.h"
 
 
 
 
 
 
+/* Flags for CallDesc */
+#define F_NONE          0x0000U /* No extra flags */
+#define F_SLOWER        0x0001U /* Function call is slower */
+
 typedef struct CallDesc CallDesc;
 struct CallDesc {
-    const char*     LongFunc;       /* Long function name */
-    short           A, X, Y;        /* Register contents */
-    const char*     ShortFunc;      /* Short function name */
+    const char* LongFunc;       /* Long function name */
+    RegContents Regs;           /* Register contents */
+    unsigned    Flags;          /* Flags from above */
+    const char* ShortFunc;      /* Short function name */
 };
 
 /* Note: The table is sorted. If there is more than one entry with the same
- * name, entries are sorted best match first, so when searching linear for
- * a match, the first one can be used because it is also the best one (or
- * at least none of the following ones are better).
- */
+** name, entries are sorted best match first, so when searching linear for
+** a match, the first one can be used because it is also the best one (or
+** at least none of the following ones are better).
+** Note^2: Ptr1 and Tmp1 aren't evaluated, because runtime routines don't
+** expect parameters here.
+*/
 static const CallDesc CallTable [] = {
-    { "addeqysp",   -1,   -1,    0, "addeq0sp"      },
-    { "laddeqysp",  -1,   -1,    0, "laddeq0sp"     },
-    { "ldaxidx",    -1,   -1,    1, "ldaxi"         },
-    { "ldaxysp",    -1,   -1,    1, "ldax0sp"       },
-    { "ldeaxidx",   -1,   -1,    3, "ldeaxi"        },
-    { "ldeaxysp",   -1,   -1,    3, "ldeax0sp"      },
-    { "pusha",       0,   -1,   -1, "pushc0"        },
-    { "pusha",       1,   -1,   -1, "pushc1"        },
-    { "pusha",       2,   -1,   -1, "pushc2"        },
-    { "pushax",      0,    0,   -1, "push0"         },
-    { "pushax",      1,    0,   -1, "push1"         },
-    { "pushax",      2,    0,   -1, "push2"         },
-    { "pushax",      3,    0,   -1, "push3"         },
-    { "pushax",      4,    0,   -1, "push4"         },
-    { "pushax",      5,    0,   -1, "push5"         },
-    { "pushax",      6,    0,   -1, "push6"         },
-    { "pushax",      7,    0,   -1, "push7"         },
-    { "pushax",     -1,    0,   -1, "pusha0"        },
-    { "pushax",     -1, 0xFF,   -1, "pushaFF"       },
-    { "pushaysp",   -1,   -1,    0, "pusha0sp"      },
-    { "staxysp",    -1,   -1,    0, "stax0sp"       },
-    { "tosaddax",   -1,    0,   -1, "tosadda0"      },
-    { "tosandax",   -1,    0,   -1, "tosanda0"      },
-    { "tosdivax",   -1,    0,   -1, "tosdiva0"      },
-    { "toseqax",    -1,    0,   -1, "toseqa0"       },
-    { "tosgeax",    -1,    0,   -1, "tosgea0"       },
-    { "tosgtax",    -1,    0,   -1, "tosgta0"       },
-    { "tosleax",    -1,    0,   -1, "toslea0"       },
-    { "tosorax",    -1,    0,   -1, "tosora0"       },
-    { "lsubeqysp",  -1,   -1,    0, "lsubeq0sp"     },
-    { "steaxysp",   -1,   -1,    0, "steax0sp"      },
-    { "subeqysp",   -1,   -1,    0, "subeq0sp"      },
-    { "tosaslax",   -1,    0,   -1, "tosasla0"      },
-    { "tosasrax",   -1,    0,   -1, "tosasra0"      },
-    { "tosltax",    -1,    0,   -1, "toslta0"       },
-    { "tosmodax",   -1,    0,   -1, "tosmoda0"      },
-    { "tosmulax",   -1,    0,   -1, "tosmula0"      },
-    { "tosneax",    -1,    0,   -1, "tosnea0"       },
-    { "tosrsubax",  -1,    0,   -1, "tosrsuba0"     },
-    { "tosshlax",   -1,    0,   -1, "tosshla0"      },
-    { "tosshrax",   -1,    0,   -1, "tosshra0"      },
-    { "tossubax",   -1,    0,   -1, "tossuba0"      },
-    { "tosudivax",  -1,    0,   -1, "tosudiva0"     },
-    { "tosugeax",   -1,    0,   -1, "tosugea0"      },
-    { "tosugtax",   -1,    0,   -1, "tosugta0"      },
-    { "tosuleax",   -1,    0,   -1, "tosulea0"      },
-    { "tosultax",   -1,    0,   -1, "tosulta0"      },
-    { "tosumodax",  -1,    0,   -1, "tosumoda0"     },
-    { "tosumulax",  -1,    0,   -1, "tosumula0"     },
-    { "tosxorax",   -1,    0,   -1, "tosxora0"      },
-    { "zzzzzzzz",   -1,   -1,   -1, "zzzzzzzz"      },
-
-#if 0
-    "tosadd0ax",         /* tosaddeax, sreg = 0 */
-    "laddeqa",           /* laddeq, sreg = 0, x = 0 */
-    "laddeq1",           /* laddeq, sreg = 0, x = 0, a = 1 */
-    "tosand0ax",         /* tosandeax, sreg = 0 */
-    "tosdiv0ax",         /* tosdiveax, sreg = 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 */
-    "tosudiv0ax",        /* tosudiveax, sreg = 0 */
-    "tosumod0ax",        /* tosumodeax, sreg = 0 */
-    "tosxor0ax",         /* tosxoreax, sreg = 0 */
-#endif
+    /* Name          A register      X register     Y register     flags     replacement */
+    {
+        "addeqysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "addeq0sp"
+    },{
+        "laddeq",
+        {
+            /*     A               X               Y             SRegLo   */
+                         1,              0, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "laddeq1"
+    },{
+        "laddeq",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "laddeqa"
+    },{
+        "laddeqysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "laddeq0sp"
+    },{
+        "ldaxidx",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              1, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "ldaxi"
+    },{
+        "ldaxysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              1, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "ldax0sp"
+    },{
+        "ldeaxidx",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              3, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "ldeaxi"
+    },{
+        "ldeaxysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              3, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "ldeax0sp"
+    },{
+        "leaaxsp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "leaa0sp"
+    },{
+        "lsubeq",
+        {
+            /*     A               X               Y             SRegLo   */
+                         1,              0, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "lsubeq1"
+    },{
+        "lsubeq",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "lsubeqa"
+    },{
+        "lsubeqysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "lsubeq0sp"
+    },{
+        "pusha",
+        {
+            /*     A               X               Y             SRegLo   */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "pushc0"
+    },{
+        "pusha",
+        {
+            /*     A               X               Y             SRegLo   */
+                         1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "pushc1"
+    },{
+        "pusha",
+        {
+            /*     A               X               Y             SRegLo   */
+                         2, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "pushc2"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         0,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "push0"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         1,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "push1"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         2,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "push2"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         3,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "push3"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         4,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "push4"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         5,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "push5"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         6,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "push6"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         7,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "push7"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "pusha0"
+    },{
+        "pushax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,           0xFF, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_SLOWER,
+        "pushaFF"
+    },{
+        "pushaysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "pusha0sp"
+    },{
+        "pusheax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         0,              0, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "pushl0"
+    },{
+        "pusheax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "push0ax"
+    },{
+        "pushwidx",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              1, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "pushw"
+    },{
+        "pushwysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              3, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "pushw0sp"
+    },{
+        "staxysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "stax0sp"
+    },{
+        "steaxysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "steax0sp"
+    },{
+        "subeqysp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "subeq0sp"
+    },{
+        "tosaddax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosadda0"
+    },{
+        "tosaddeax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosadd0ax"
+    },{
+        "tosandax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosanda0"
+    },{
+        "tosandeax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosand0ax"
+    },{
+        "tosdivax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosdiva0"
+    },{
+        "tosdiveax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosdiv0ax"
+    },{
+        "toseqax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         0,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "toseq00"
+    },{
+        "toseqax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "toseqa0"
+    },{
+        "tosgeax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         0,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosge00"
+    },{
+        "tosgeax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosgea0"
+    },{
+        "tosgtax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         0,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosgt00"
+    },{
+        "tosgtax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosgta0"
+    },{
+        "tosicmp",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosicmp0"
+    },{
+        "tosleax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         0,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosle00"
+    },{
+        "tosleax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "toslea0"
+    },{
+        "tosltax",
+        {
+            /*     A               X               Y             SRegLo   */
+                         0,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "toslt00"
+    },{
+        "tosltax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "toslta0"
+    },{
+        "tosmodax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosmoda0"
+    },{
+        "tosmodeax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosmod0ax"
+    },{
+        "tosmulax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosmula0"
+    },{
+        "tosmuleax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosmul0ax"
+    },{
+        "tosneax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosnea0"
+    },{
+        "tosorax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosora0"
+    },{
+        "tosoreax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosor0ax"
+    },{
+        "tosrsubax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosrsuba0"
+    },{
+        "tosrsubeax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosrsub0ax"
+    },{
+        "tossubax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tossuba0"
+    },{
+        "tossubeax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tossub0ax"
+    },{
+        "tosudivax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosudiva0"
+    },{
+        "tosudiveax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosudiv0ax"
+    },{
+        "tosugeax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosugea0"
+    },{
+        "tosugtax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosugta0"
+    },{
+        "tosuleax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosulea0"
+    },{
+        "tosultax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosulta0"
+    },{
+        "tosumodax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosumoda0"
+    },{
+        "tosumodeax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosumod0ax"
+    },{
+        "tosumulax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosumula0"
+    },{
+        "tosumuleax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosumul0ax"
+    },{
+        "tosxorax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL,              0, UNKNOWN_REGVAL, UNKNOWN_REGVAL,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosxora0"
+    },{
+        "tosxoreax",
+        {
+            /*     A               X               Y             SRegLo   */
+            UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL,              0,
+            /*   SRegHi          Ptr1Lo          Ptr1Hi           Tmp1    */
+                         0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, UNKNOWN_REGVAL
+        },
+        F_NONE,
+        "tosxor0ax"
+    },
+
 };
 #define CALL_COUNT (sizeof(CallTable) / sizeof(CallTable[0]))
 
 
 
 /*****************************************************************************/
-/*                                         Helpers                                  */
+/*                                  Helpers                                  */
 /*****************************************************************************/
 
 
 
 static const CallDesc* FindCall (const char* Name)
 /* Find the function with the given name. Return a pointer to the table entry
- * or NULL if the function was not found.
- */
+** or NULL if the function was not found.
+*/
 {
     /* Do a binary search */
     int First = 0;
-    int Last = (sizeof(CallTable) / sizeof(CallTable[0])) - 1;
-    int Current;
-    int Result;
+    int Last = CALL_COUNT - 1;
     int Found = 0;
 
     while (First <= Last) {
 
-               /* Set current to mid of range */
-       Current = (Last + First) / 2;
-
-               /* Do a compare */
-               Result = strcmp (CallTable[Current].LongFunc, Name);
-       if (Result < 0) {
-           First = Current + 1;
-       } else {
-           Last = Current - 1;
-           if (Result == 0) {
-                       /* Found. Repeat the procedure until the first of all entries
-                 * with the same name is found.
-                 */
-               Found = 1;
-           }
-       }
+        /* Set current to mid of range */
+        int Current = (Last + First) / 2;
 
+        /* Do a compare */
+        int Result = strcmp (CallTable[Current].LongFunc, Name);
+        if (Result < 0) {
+            First = Current + 1;
+        } else {
+            Last = Current - 1;
+            if (Result == 0) {
+                /* Found. Repeat the procedure until the first of all entries
+                ** with the same name is found.
+                */
+                Found = 1;
+            }
+        }
     }
 
     /* Return the first entry if found, or NULL otherwise */
@@ -187,43 +852,67 @@ static const CallDesc* FindCall (const char* Name)
 
 
 
+static int RegMatch (short Expected, short Actual)
+/* Check for a register match. If Expected has a value, it must be identical
+** to Actual.
+*/
+{
+    return RegValIsUnknown (Expected) || (Expected == Actual);
+}
+
+
+
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
 
 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.
- */
+** This routine does not work standalone, it needs a following register load
+** removal pass.
+*/
 {
     CodeEntry* E;
     unsigned Changes = 0;
     unsigned I;
 
-    /* Generate register info for the following step */
-    CS_GenRegInfo (S);
+    /* Are we optimizing for size */
+    int OptForSize = (S->CodeSizeFactor < 100);
 
     /* Walk over the entries */
     I = 0;
     while (I < CS_GetEntryCount (S)) {
 
-       /* Get next entry */
-               E = CS_GetEntry (S, I);
+        const CallDesc* D;
+
+        /* Get next entry */
+        E = CS_GetEntry (S, I);
+
+        /* Check if it's a subroutine call */
+        if (E->OPC == OP65_JSR && (D = FindCall (E->Arg)) != 0) {
+
+            /* Get input register info for this insn */
+            const RegContents* In = &E->RI->In;
 
-       /* Check if it's a subroutine call */
-       if (E->OPC == OP65_JSR) {
+            /* FindCall finds the first entry that matches our function name.
+            ** The names are listed in "best match" order, so search for the
+            ** first one, that fulfills our conditions.
+            */
+            while (1) {
 
-           /* Check for any of the known functions. */
-            const CallDesc* D = FindCall (E->Arg);
-            while (D && strcmp (D->LongFunc, E->Arg) == 0) {
-                /* Check the registers */
-                if ((D->A < 0 || D->A == E->RI->In.RegA) &&
-                    (D->X < 0 || D->X == E->RI->In.RegX) &&
-                    (D->Y < 0 || D->Y == E->RI->In.RegY)) {
-                    /* Ok, match for all registers */
+                /* Check the registers and allow slower code only if
+                ** optimizing for size.
+                */
+                if ((OptForSize || (D->Flags & F_SLOWER) == 0)          &&
+                    RegMatch (D->Regs.RegA,    In->RegA)                &&
+                    RegMatch (D->Regs.RegX,    In->RegX)                &&
+                    RegMatch (D->Regs.RegY,    In->RegY)                &&
+                    RegMatch (D->Regs.SRegLo,  In->SRegLo)              &&
+                    RegMatch (D->Regs.SRegHi,  In->SRegHi)) {
+
+                    /* Ok, match for all conditions */
                     CodeEntry* X;
                     X = NewCodeEntry (E->OPC, E->AM, D->ShortFunc, 0, E->LI);
                     CS_InsertEntry (S, X, I+1);
@@ -231,19 +920,25 @@ unsigned OptSize1 (CodeSeg* S)
 
                     /* Remember that we had changes */
                     ++Changes;
+
+                    /* Done */
+                    break;
+                }
+
+                /* Next table entry, bail out if next entry not valid */
+                if (++D >= CallTable + CALL_COUNT ||
+                    strcmp (D->LongFunc, E->Arg) != 0) {
+                    /* End of table or entries reached */
+                    break;
                 }
-                ++D;
             }
         }
 
-       /* Next entry */
-       ++I;
+        /* Next entry */
+        ++I;
 
     }
 
-    /* Free register info */
-    CS_FreeRegInfo (S);
-
     /* Return the number of changes made */
     return Changes;
 }
@@ -252,99 +947,90 @@ unsigned OptSize1 (CodeSeg* S)
 
 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.
- */
+** 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);
+        /* Get next entry */
+        CodeEntry* E = CS_GetEntry (S, I);
 
         /* Get the input registers */
         const RegContents* In = &E->RI->In;
 
-       /* 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 == In->RegX) {
-                       X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI);
-                   } else if (Val == In->RegY) {
-                       X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI);
-                   } else if (RegValIsKnown (In->RegA) && CPU >= CPU_65C02) {
-                       if (Val == ((In->RegA - 1) & 0xFF)) {
-                           X = NewCodeEntry (OP65_DEA, AM65_IMP, 0, 0, E->LI);
-                       } else if (Val == ((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 (RegValIsKnown (In->RegX) && Val == ((In->RegX - 1) & 0xFF)) {
-                       X = NewCodeEntry (OP65_DEX, AM65_IMP, 0, 0, E->LI);
-                           } else if (RegValIsKnown (In->RegX) && Val == ((In->RegX + 1) & 0xFF)) {
-                       X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, E->LI);
-                   } else if (Val == In->RegA) {
-                       X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI);
+        /* Assume we have no replacement */
+        CodeEntry* X = 0;
+
+        /* Check the instruction */
+        switch (E->OPC) {
+
+            case OP65_LDA:
+                if (CE_IsConstImm (E)) {
+                    short Val = (short) E->Num;
+                    if (Val == In->RegX) {
+                        X = NewCodeEntry (OP65_TXA, AM65_IMP, 0, 0, E->LI);
+                    } else if (Val == In->RegY) {
+                        X = NewCodeEntry (OP65_TYA, AM65_IMP, 0, 0, E->LI);
+                    } else if (RegValIsKnown (In->RegA) && (CPUIsets[CPU] & CPU_ISET_65SC02) != 0) {
+                        if (Val == ((In->RegA - 1) & 0xFF)) {
+                            X = NewCodeEntry (OP65_DEA, AM65_IMP, 0, 0, E->LI);
+                        } else if (Val == ((In->RegA + 1) & 0xFF)) {
+                            X = NewCodeEntry (OP65_INA, AM65_IMP, 0, 0, E->LI);
+                        }
                     }
-               }
-               break;
-
-                   case OP65_LDY:
-               if (CE_KnownImm (E)) {
-                   short Val = (short) E->Num;
-                   if (RegValIsKnown (In->RegY) && Val == ((In->RegY - 1) & 0xFF)) {
-                       X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, E->LI);
-                   } else if (RegValIsKnown (In->RegY) && Val == ((In->RegY + 1) & 0xFF)) {
-                       X = NewCodeEntry (OP65_INY, AM65_IMP, 0, 0, E->LI);
-                   } else if (Val == 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);
-           CS_DelEntry (S, I);
-           ++Changes;
-       }
-
-       /* Next entry */
-       ++I;
+                }
+                break;
 
-    }
+            case OP65_LDX:
+                if (CE_IsConstImm (E)) {
+                    short Val = (short) E->Num;
+                    if (RegValIsKnown (In->RegX) && Val == ((In->RegX - 1) & 0xFF)) {
+                        X = NewCodeEntry (OP65_DEX, AM65_IMP, 0, 0, E->LI);
+                    } else if (RegValIsKnown (In->RegX) && Val == ((In->RegX + 1) & 0xFF)) {
+                        X = NewCodeEntry (OP65_INX, AM65_IMP, 0, 0, E->LI);
+                    } else if (Val == In->RegA) {
+                        X = NewCodeEntry (OP65_TAX, AM65_IMP, 0, 0, E->LI);
+                    }
+                }
+                break;
 
-    /* Free register info */
-    CS_FreeRegInfo (S);
+            case OP65_LDY:
+                if (CE_IsConstImm (E)) {
+                    short Val = (short) E->Num;
+                    if (RegValIsKnown (In->RegY) && Val == ((In->RegY - 1) & 0xFF)) {
+                        X = NewCodeEntry (OP65_DEY, AM65_IMP, 0, 0, E->LI);
+                    } else if (RegValIsKnown (In->RegY) && Val == ((In->RegY + 1) & 0xFF)) {
+                        X = NewCodeEntry (OP65_INY, AM65_IMP, 0, 0, E->LI);
+                    } else if (Val == In->RegA) {
+                        X = NewCodeEntry (OP65_TAY, AM65_IMP, 0, 0, E->LI);
+                    }
+                }
+                break;
 
-    /* Return the number of changes made */
-    return Changes;
-}
+            default:
+                /* Avoid gcc warnings */
+                break;
+
+        }
+
+        /* Insert the replacement if we have one */
+        if (X) {
+            CS_InsertEntry (S, X, I+1);
+            CS_DelEntry (S, I);
+            ++Changes;
+        }
 
+        /* Next entry */
+        ++I;
 
+    }
 
+    /* Return the number of changes made */
+    return Changes;
+}