sourcepawn/compiler/sc7.scp
author David Anderson <dvander@alliedmods.net>
Sun Nov 25 18:50:13 2007 +0000 (2007-11-25)
changeset 1725 ea875bcbc286
parent 365 d830b2b0414f
permissions -rw-r--r--
small clarification to param2 in MenuAction_End
     1 /*  Pawn compiler - Peephole optimizer "sequences" strings (plain
     2  *                   and compressed formats)
     3  *
     4  *  Copyright (c) ITB CompuPhase, 2000-2006
     5  *
     6  *  This software is provided "as-is", without any express or implied warranty.
     7  *  In no event will the authors be held liable for any damages arising from
     8  *  the use of this software.
     9  *
    10  *  Permission is granted to anyone to use this software for any purpose,
    11  *  including commercial applications, and to alter it and redistribute it
    12  *  freely, subject to the following restrictions:
    13  *
    14  *  1.  The origin of this software must not be misrepresented; you must not
    15  *      claim that you wrote the original software. If you use this software in
    16  *      a product, an acknowledgment in the product documentation would be
    17  *      appreciated but is not required.
    18  *  2.  Altered source versions must be plainly marked as such, and must not be
    19  *      misrepresented as being the original software.
    20  *  3.  This notice may not be removed or altered from any source distribution.
    21  *
    22  *  Version: $Id$
    23  */
    24 
    25 SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2]);
    26 
    27 #define SCPACK_TERMINATOR ,     /* end each section with a comma */
    28 
    29 #define SCPACK_TABLE sequences_table
    30 /*-*SCPACK start of pair table, do not change or remove this line */
    31 unsigned char sequences_table[][2] = {
    32   {49,33}, {37,128}, {32,129}, {32,37}, {114,105}, {112,132}, {46,133}, {97,100}, {46,97}, {136,108}, {137,116}, {115,104}, {111,135}, {117,139}, {112,141}, {108,140},
    33   {131,50}, {144,33}, {46,115}, {138,33}, {59,36}, {134,130}, {143,146}, {115,116}, {134,145}, {110,151}, {111,153}, {99,154}, {112,147}, {135,100}, {134,33}, {114,33},
    34   {111,156}, {112,160}, {46,99}, {138,130}, {142,158}, {131,51}, {150,152}, {112,33}, {120,167}, {101,168}, {148,169}, {97,159}, {112,171}, {148,172}, {165,33}, {173,142},
    35   {122,101}, {176,114}, {101,113}, {110,100}, {149,164}, {157,114}, {33,161}, {131,49}, {103,33}, {157,33}, {104,184}, {99,186}, {120,187}, {98,111}, {118,101}, {111,190},
    36   {109,191}, {130,170}, {131,52}, {106,177}, {138,145}, {180,166}, {192,147}, {108,162}, {163,166}, {143,149}, {115,174}, {117,179}, {139,199}, {203,202}, {189,205}, {105,100},
    37   {115,103}, {115,108}, {207,120}, {195,130}, {46,135}, {178,33}, {212,114}, {204,134}, {155,149}, {142,162}, {183,145}, {150,149}, {143,152}, {194,33}, {130,175}, {97,179},
    38   {177,111}, {182,185}, {143,46}, {183,144}, {155,152}, {145,175}, {114,101}, {230,102}, {108,231}, {101,115}, {233,115}, {114,116}, {142,147}, {105,33}, {155,163}, {178,130},
    39   {215,32}, {240,50}, {143,196}, {155,197}, {181,197}, {181,200}, {108,210}, {46,98}, {241,225}, {208,235}, {209,234}, {224,158}, {143,163}, {150,163}, {155,200}
    40 };
    41 /*-*SCPACK end of pair table, do not change or remove this line */
    42 
    43 #define seqsize(o,p)    (opcodes(o)+opargs(p))
    44 typedef struct {
    45   char *find;
    46   char *replace;
    47   int savesize;         /* number of bytes saved (in bytecode) */
    48 } SEQUENCE;
    49 static SEQUENCE sequences_cmp[] = {
    50   /* A very common sequence in four varieties
    51    *    load.s.pri n1           load.s.pri n2
    52    *    push.pri                load.s.alt n1
    53    *    load.s.pri n2           -
    54    *    pop.alt                 -
    55    *    --------------------------------------
    56    *    load.pri n1             load.s.pri n2
    57    *    push.pri                load.alt n1
    58    *    load.s.pri n2           -
    59    *    pop.alt                 -
    60    *    --------------------------------------
    61    *    load.s.pri n1           load.pri n2
    62    *    push.pri                load.s.alt n1
    63    *    load.pri n2             -
    64    *    pop.alt                 -
    65    *    --------------------------------------
    66    *    load.pri n1             load.pri n2
    67    *    push.pri                load.alt n1
    68    *    load.pri n2             -
    69    *    pop.alt                 -
    70    */
    71   {
    72     #ifdef SCPACK
    73       "load.s.pri %1!push.pri!load.s.pri %2!pop.alt!",
    74       "load.s.pri %2!load.s.alt %1!",
    75     #else
    76       "\226\305\241",
    77       "\246\375",
    78     #endif
    79     seqsize(4,2) - seqsize(2,2)
    80   },
    81   {
    82     #ifdef SCPACK
    83       "load.pri %1!push.pri!load.s.pri %2!pop.alt!",
    84       "load.s.pri %2!load.alt %1!",
    85     #else
    86       "\217\305\241",
    87       "\246\374",
    88     #endif
    89     seqsize(4,2) - seqsize(2,2)
    90   },
    91   {
    92     #ifdef SCPACK
    93       "load.s.pri %1!push.pri!load.pri %2!pop.alt!",
    94       "load.pri %2!load.s.alt %1!",
    95     #else
    96       "\226\264\334\241",
    97       "\334\375",
    98     #endif
    99     seqsize(4,2) - seqsize(2,2)
   100   },
   101   {
   102     #ifdef SCPACK
   103       "load.pri %1!push.pri!load.pri %2!pop.alt!",
   104       "load.pri %2!load.alt %1!",
   105     #else
   106       "\217\264\334\241",
   107       "\334\374",
   108     #endif
   109     seqsize(4,2) - seqsize(2,2)
   110   },
   111   /* (#1#) The above also occurs with "addr.pri" (array
   112    * indexing) as the first line; so that adds 2 cases.
   113    */
   114   {
   115     #ifdef SCPACK
   116       "addr.pri %1!push.pri!load.s.pri %2!pop.alt!",
   117       "addr.alt %1!load.s.pri %2!",
   118     #else
   119       "\364\241",
   120       "\365",
   121     #endif
   122     seqsize(4,2) - seqsize(2,2)
   123   },
   124   {
   125     #ifdef SCPACK
   126       "addr.pri %1!push.pri!load.pri %2!pop.alt!",
   127       "addr.alt %1!load.pri %2!",
   128     #else
   129       "\265\264\334\241",
   130       "\265\243\334",
   131     #endif
   132     seqsize(4,2) - seqsize(2,2)
   133   },
   134   /* And the same sequence with const.pri as either the first
   135    * or the second load instruction: four more cases.
   136    */
   137   {
   138     #ifdef SCPACK
   139       "const.pri %1!push.pri!load.s.pri %2!pop.alt!",
   140       "load.s.pri %2!const.alt %1!",
   141     #else
   142       "\363\241",
   143       "\246\356",
   144     #endif
   145     seqsize(4,2) - seqsize(2,2)
   146   },
   147   {
   148     #ifdef SCPACK
   149       "const.pri %1!push.pri!load.pri %2!pop.alt!",
   150       "load.pri %2!const.alt %1!",
   151     #else
   152       "\233\264\334\241",
   153       "\334\356",
   154     #endif
   155     seqsize(4,2) - seqsize(2,2)
   156   },
   157   {
   158     #ifdef SCPACK
   159       "load.s.pri %1!push.pri!const.pri %2!pop.alt!",
   160       "const.pri %2!load.s.alt %1!",
   161     #else
   162       "\226\264\344\241",
   163       "\344\375",
   164     #endif
   165     seqsize(4,2) - seqsize(2,2)
   166   },
   167   {
   168     #ifdef SCPACK
   169       "load.pri %1!push.pri!const.pri %2!pop.alt!",
   170       "const.pri %2!load.alt %1!",
   171     #else
   172       "\217\264\344\241",
   173       "\344\374",
   174     #endif
   175     seqsize(4,2) - seqsize(2,2)
   176   },
   177   /* The same as above, but now with "addr.pri" (array
   178    * indexing) on the first line and const.pri on
   179    * the second.
   180    */
   181   {
   182     #ifdef SCPACK
   183       "addr.pri %1!push.pri!const.pri %2!pop.alt!",
   184       "addr.alt %1!const.pri %2!",
   185     #else
   186       "\265\264\344\241",
   187       "\265\243\344",
   188     #endif
   189     seqsize(4,2) - seqsize(2,2)
   190   },
   191   {
   192     #ifdef SCPACK
   193       "addr.pri %1!push.pri!zero.pri!pop.alt!",
   194       "addr.alt %1!zero.pri!",
   195     #else
   196       "\265\264\373\241",
   197       "\265\243\373",
   198     #endif
   199     seqsize(4,1) - seqsize(2,1)
   200   },
   201   /* ??? add references */
   202   /* Chained relational operators can contain sequences like:
   203    *    move.pri                load.s.pri n1
   204    *    push.pri                -
   205    *    load.s.pri n1           -
   206    *    pop.alt                 -
   207    * The above also accurs for "load.pri" and for "const.pri",
   208    * so add another two cases.
   209    */
   210   {
   211     #ifdef SCPACK
   212       "move.pri!push.pri!load.s.pri %1!pop.alt!",
   213       "load.s.pri %1!",
   214     #else
   215       "\300\236\244\333\241",
   216       "\333",
   217     #endif
   218     seqsize(4,1) - seqsize(1,1)
   219   },
   220   {
   221     #ifdef SCPACK
   222       "move.pri!push.pri!load.pri %1!pop.alt!",
   223       "load.pri %1!",
   224     #else
   225       "\300\236\244\311\241",
   226       "\311",
   227     #endif
   228     seqsize(4,1) - seqsize(1,1)
   229   },
   230   {
   231     #ifdef SCPACK
   232       "move.pri!push.pri!const.pri %1!pop.alt!",
   233       "const.pri %1!",
   234     #else
   235       "\300\236\244\330\241",
   236       "\330",
   237     #endif
   238     seqsize(4,1) - seqsize(1,1)
   239   },
   240   /* More optimizations for chained relational operators; the
   241    * continuation sequences can be simplified if they turn out
   242    * to be termination sequences:
   243    *    xchg                    sless       also for sless, sgeq and sleq
   244    *    sgrtr                   pop.alt
   245    *    swap.alt                and
   246    *    and                     ;$exp
   247    *    pop.alt                 -
   248    *    ;$exp                   -
   249    *    --------------------------------------
   250    *    xchg                    sless       also for sless, sgeq and sleq
   251    *    sgrtr                   pop.alt
   252    *    swap.alt                and
   253    *    and                     jzer n1
   254    *    pop.alt                 -
   255    *    jzer n1                 -
   256    *    --------------------------------------
   257    *    xchg                    jsgeq  n1   also for sless, sgeq and sleq
   258    *    sgrtr                   ;$exp       (occurs for non-chained comparisons)
   259    *    jzer n1                 -
   260    *    ;$exp                   -
   261    *    --------------------------------------
   262    *    xchg                    sless       also for sless, sgeq and sleq
   263    *    sgrtr                   ;$exp       (occurs for non-chained comparisons)
   264    *    ;$exp                   -
   265    */
   266   {
   267     #ifdef SCPACK
   268       "xchg!sgrtr!swap.alt!and!pop.alt!;$exp!",
   269       "sless!pop.alt!and!;$exp!",
   270     #else
   271       "\274\371\237swa\234\337\266\252",
   272       "\372\266\337!\252",
   273     #endif
   274     seqsize(5,0) - seqsize(3,0)
   275   },
   276   {
   277     #ifdef SCPACK
   278       "xchg!sless!swap.alt!and!pop.alt!;$exp!",
   279       "sgrtr!pop.alt!and!;$exp!",
   280     #else
   281       "\274\372!swa\234\337\266\252",
   282       "\371\237\241\337!\252",
   283     #endif
   284     seqsize(5,0) - seqsize(3,0)
   285   },
   286   {
   287     #ifdef SCPACK
   288       "xchg!sgeq!swap.alt!and!pop.alt!;$exp!",
   289       "sleq!pop.alt!and!;$exp!",
   290     #else
   291       "\274\320\325swa\234\337\266\252",
   292       "\321\262\266\337!\252",
   293     #endif
   294     seqsize(5,0) - seqsize(3,0)
   295   },
   296   {
   297     #ifdef SCPACK
   298       "xchg!sleq!swap.alt!and!pop.alt!;$exp!",
   299       "sgeq!pop.alt!and!;$exp!",
   300     #else
   301       "\274\321\325swa\234\337\266\252",
   302       "\320\262\266\337!\252",
   303     #endif
   304     seqsize(5,0) - seqsize(3,0)
   305   },
   306   {
   307     #ifdef SCPACK
   308       "xchg!sgrtr!swap.alt!and!pop.alt!jzer %1!",
   309       "sless!pop.alt!and!jzer %1!",
   310     #else
   311       "\274\371\237swa\234\337\266\323",
   312       "\372\266\337!\323",
   313     #endif
   314     seqsize(5,0) - seqsize(3,0)
   315   },
   316   {
   317     #ifdef SCPACK
   318       "xchg!sless!swap.alt!and!pop.alt!jzer %1!",
   319       "sgrtr!pop.alt!and!jzer %1!",
   320     #else
   321       "\274\372!swa\234\337\266\323",
   322       "\371\237\241\337!\323",
   323     #endif
   324     seqsize(5,0) - seqsize(3,0)
   325   },
   326   {
   327     #ifdef SCPACK
   328       "xchg!sgeq!swap.alt!and!pop.alt!jzer %1!",
   329       "sleq!pop.alt!and!jzer %1!",
   330     #else
   331       "\274\320\325swa\234\337\266\323",
   332       "\321\262\266\337!\323",
   333     #endif
   334     seqsize(5,0) - seqsize(3,0)
   335   },
   336   {
   337     #ifdef SCPACK
   338       "xchg!sleq!swap.alt!and!pop.alt!jzer %1!",
   339       "sgeq!pop.alt!and!jzer %1!",
   340     #else
   341       "\274\321\325swa\234\337\266\323",
   342       "\320\262\266\337!\323",
   343     #endif
   344     seqsize(5,0) - seqsize(3,0)
   345   },
   346   {
   347     #ifdef SCPACK
   348       "xchg!sgrtr!jzer %1!;$exp!",
   349       "jsgeq %1!;$exp!",
   350     #else
   351       "\274\371\237\303\301",
   352       "j\320\262\301",
   353     #endif
   354     seqsize(3,1) - seqsize(1,1)
   355   },
   356   {
   357     #ifdef SCPACK
   358       "xchg!sless!jzer %1!;$exp!",
   359       "jsleq %1!;$exp!",
   360     #else
   361       "\274\372!\303\301",
   362       "j\321\262\301",
   363     #endif
   364     seqsize(3,1) - seqsize(1,1)
   365   },
   366   {
   367     #ifdef SCPACK
   368       "xchg!sgeq!jzer %1!;$exp!",
   369       "jsgrtr %1!;$exp!",
   370     #else
   371       "\274\320\325\303\301",
   372       "j\371r\301",
   373     #endif
   374     seqsize(3,1) - seqsize(1,1)
   375   },
   376   {
   377     #ifdef SCPACK
   378       "xchg!sleq!jzer %1!;$exp!",
   379       "jsless %1!;$exp!",
   380     #else
   381       "\274\321\325\303\301",
   382       "j\372\301",
   383     #endif
   384     seqsize(3,1) - seqsize(1,1)
   385   },
   386   {
   387     #ifdef SCPACK
   388       "xchg!sgrtr!;$exp!",
   389       "sless!;$exp!",
   390     #else
   391       "\274\371\237\252",
   392       "\372!\252",
   393     #endif
   394     seqsize(2,0) - seqsize(1,0)
   395   },
   396   {
   397     #ifdef SCPACK
   398       "xchg!sless!;$exp!",
   399       "sgrtr!;$exp!",
   400     #else
   401       "\274\372!\252",
   402       "\371\237\252",
   403     #endif
   404     seqsize(2,0) - seqsize(1,0)
   405   },
   406   {
   407     #ifdef SCPACK
   408       "xchg!sgeq!;$exp!",
   409       "sleq!;$exp!",
   410     #else
   411       "\274\320\325\252",
   412       "\321\325\252",
   413     #endif
   414     seqsize(2,0) - seqsize(1,0)
   415   },
   416   {
   417     #ifdef SCPACK
   418       "xchg!sleq!;$exp!",
   419       "sgeq!;$exp!",
   420     #else
   421       "\274\321\325\252",
   422       "\320\325\252",
   423     #endif
   424     seqsize(2,0) - seqsize(1,0)
   425   },
   426   /* The entry to chained operators is also opt to optimization
   427    *    load.s.pri n1           load.s.pri n2
   428    *    load.s.alt n2           load.s.alt n1
   429    *    xchg                    -
   430    *    --------------------------------------
   431    *    load.s.pri n1           load.pri n2
   432    *    load.alt n2             load.s.alt n1
   433    *    xchg                    -
   434    *    --------------------------------------
   435    *    load.s.pri n1           const.pri n2
   436    *    const.alt n2            load.s.alt n1
   437    *    xchg                    -
   438    *    --------------------------------------
   439    * and all permutations...
   440    */
   441   {
   442     #ifdef SCPACK
   443       "load.s.pri %1!load.s.alt %2!xchg!",
   444       "load.s.pri %2!load.s.alt %1!",
   445     #else
   446       "\333\226\304\274",
   447       "\246\375",
   448     #endif
   449     seqsize(3,2) - seqsize(2,2)
   450   },
   451   {
   452     #ifdef SCPACK
   453       "load.s.pri %1!load.alt %2!xchg!",
   454       "load.pri %2!load.s.alt %1!",
   455     #else
   456       "\333\362\274",
   457       "\334\375",
   458     #endif
   459     seqsize(3,2) - seqsize(2,2)
   460   },
   461   {
   462     #ifdef SCPACK
   463       "load.s.pri %1!const.alt %2!xchg!",
   464       "const.pri %2!load.s.alt %1!",
   465     #else
   466       "\333\233\304\274",
   467       "\344\375",
   468     #endif
   469     seqsize(3,2) - seqsize(2,2)
   470   },
   471   {
   472     #ifdef SCPACK
   473       "load.pri %1!load.s.alt %2!xchg!",
   474       "load.s.pri %2!load.alt %1!",
   475     #else
   476       "\311\226\304\274",
   477       "\246\374",
   478     #endif
   479     seqsize(3,2) - seqsize(2,2)
   480   },
   481   {
   482     #ifdef SCPACK
   483       "load.pri %1!load.alt %2!xchg!",
   484       "load.pri %2!load.alt %1!",
   485     #else
   486       "\311\362\274",
   487       "\334\374",
   488     #endif
   489     seqsize(3,2) - seqsize(2,2)
   490   },
   491   {
   492     #ifdef SCPACK
   493       "load.pri %1!const.alt %2!xchg!",
   494       "const.pri %2!load.alt %1!",
   495     #else
   496       "\311\233\304\274",
   497       "\344\374",
   498     #endif
   499     seqsize(3,2) - seqsize(2,2)
   500   },
   501   {
   502     #ifdef SCPACK
   503       "const.pri %1!load.s.alt %2!xchg!",
   504       "load.s.pri %2!const.alt %1!",
   505     #else
   506       "\330\226\304\274",
   507       "\246\356",
   508     #endif
   509     seqsize(3,2) - seqsize(2,2)
   510   },
   511   {
   512     #ifdef SCPACK
   513       "const.pri %1!load.alt %2!xchg!",
   514       "load.pri %2!const.alt %1!",
   515     #else
   516       "\330\362\274",
   517       "\334\356",
   518     #endif
   519     seqsize(3,2) - seqsize(2,2)
   520   },
   521   /* some sequences where PRI is moved to ALT can be optimized
   522    * further when considering what follows
   523    *    move.alt                const.alt n1
   524    *    const.pri %1            -
   525    *    xchg                    -
   526    * (also for load.s.pri and load.pri)
   527    *    --------------------------------------
   528    *    lref.pri %1             lref.alt %1
   529    *    move.alt                [load.pri %2]
   530    *    [load.pri %2]           -
   531    * (where [load.pri %2] may also be another operatrion loading PRI)
   532    */
   533   {
   534     #ifdef SCPACK
   535       "move.alt!const.pri %1!xchg!",
   536       "const.alt %1!",
   537     #else
   538       "\306\330\274",
   539       "\356",
   540     #endif
   541     seqsize(3,1) - seqsize(1,1)
   542   },
   543   {
   544     #ifdef SCPACK
   545       "move.alt!load.pri %1!xchg!",
   546       "load.alt %1!",
   547     #else
   548       "\306\311\274",
   549       "\374",
   550     #endif
   551     seqsize(3,1) - seqsize(1,1)
   552   },
   553   {
   554     #ifdef SCPACK
   555       "move.alt!load.s.pri %1!xchg!",
   556       "load.s.alt %1!",
   557     #else
   558       "\306\333\274",
   559       "\375",
   560     #endif
   561     seqsize(3,1) - seqsize(1,1)
   562   },
   563   /* ----- */
   564   {
   565     #ifdef SCPACK
   566       "lref.pri %1!move.alt!load.pri %2!",
   567       "lref.alt %1!load.pri %2!",
   568     #else
   569       "\350\225\306\334",
   570       "\350\243\334",
   571     #endif
   572     seqsize(3,2) - seqsize(2,2)
   573   },
   574   {
   575     #ifdef SCPACK
   576       "lref.pri %1!move.alt!load.s.pri %2!",
   577       "lref.alt %1!load.s.pri %2!",
   578     #else
   579       "\350\225\306\246",
   580       "\350\310",
   581     #endif
   582     seqsize(3,2) - seqsize(2,2)
   583   },
   584   {
   585     #ifdef SCPACK
   586       "lref.pri %1!move.alt!const.pri %2!",
   587       "lref.alt %1!const.pri %2!",
   588     #else
   589       "\350\225\306\344",
   590       "\350\243\344",
   591     #endif
   592     seqsize(3,2) - seqsize(2,2)
   593   },
   594   {
   595     #ifdef SCPACK
   596       "lref.s.pri %1!move.alt!load.pri %2!",
   597       "lref.s.alt %1!load.pri %2!",
   598     #else
   599       "\350\222\225\306\334",
   600       "\350\222\243\334",
   601     #endif
   602     seqsize(3,2) - seqsize(2,2)
   603   },
   604   {
   605     #ifdef SCPACK
   606       "lref.s.pri %1!move.alt!load.s.pri %2!",
   607       "lref.s.alt %1!load.s.pri %2!",
   608     #else
   609       "\350\222\225\306\246",
   610       "\350\222\310",
   611     #endif
   612     seqsize(3,2) - seqsize(2,2)
   613   },
   614   {
   615     #ifdef SCPACK
   616       "lref.s.pri %1!move.alt!const.pri %2!",
   617       "lref.s.alt %1!const.pri %2!",
   618     #else
   619       "\350\222\225\306\344",
   620       "\350\222\243\344",
   621     #endif
   622     seqsize(3,2) - seqsize(2,2)
   623   },
   624   /* Array indexing can merit from special instructions.
   625    * Simple indexed array lookup can be optimized quite
   626    * a bit.
   627    *    addr.pri n1             addr.alt n1
   628    *    push.pri                load.s.pri n2
   629    *    load.s.pri n2           bounds n3
   630    *    bounds n3               lidx.b n4
   631    *    shl.c.pri n4            -
   632    *    pop.alt                 -
   633    *    add                     -
   634    *    load.i                  -
   635    *
   636    * And to prepare for storing a value in an array
   637    *    addr.pri n1             addr.alt n1
   638    *    push.pri                load.s.pri n2
   639    *    load.s.pri n2           bounds n3
   640    *    bounds n3               idxaddr.b n4
   641    *    shl.c.pri n4            -
   642    *    pop.alt                 -
   643    *    add                     -
   644    *
   645    * Notes (additional cases):
   646    * 1. instruction addr.pri can also be const.pri (for
   647    *    global arrays)
   648    * 2. the bounds instruction can be absent
   649    * 3. when "n4" (the shift value) is the 2 (with 32-bit cells), use the
   650    *    even more optimal instructions LIDX and IDDXADDR
   651    *
   652    * If the array index is more complex, one can only optimize
   653    * the last four instructions:
   654    *    shl.c.pri n1            pop.alt
   655    *    pop.alt                 lidx.b n1
   656    *    add                     -
   657    *    loadi                   -
   658    *    --------------------------------------
   659    *    shl.c.pri n1            pop.alt
   660    *    pop.alt                 idxaddr.b n1
   661    *    add                     -
   662    */
   663 #if !defined BIT16
   664   /* loading from array, "cell" shifted */
   665   {
   666     #ifdef SCPACK
   667       "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!load.i!",
   668       "addr.alt %1!load.s.pri %2!bounds %3!lidx!",
   669     #else
   670       "\364\316\370\342\355",
   671       "\365\316\366!",
   672     #endif
   673     seqsize(8,4) - seqsize(4,3)
   674   },
   675   {
   676     #ifdef SCPACK
   677       "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!load.i!",
   678       "const.alt %1!load.s.pri %2!bounds %3!lidx!",
   679     #else
   680       "\363\316\370\342\355",
   681       "\376\316\366!",
   682     #endif
   683     seqsize(8,4) - seqsize(4,3)
   684   },
   685   {
   686     #ifdef SCPACK
   687       "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!load.i!",
   688       "addr.alt %1!load.s.pri %2!lidx!",
   689     #else
   690       "\364\370\342\355",
   691       "\365\366!",
   692     #endif
   693     seqsize(7,3) - seqsize(3,2)
   694   },
   695   {
   696     #ifdef SCPACK
   697       "const.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!load.i!",
   698       "const.alt %1!load.s.pri %2!lidx!",
   699     #else
   700       "\363\370\342\355",
   701       "\376\366!",
   702     #endif
   703     seqsize(7,3) - seqsize(3,2)
   704   },
   705 #endif
   706   /* loading from array, not "cell" shifted */
   707   {
   708     #ifdef SCPACK
   709       "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!load.i!",
   710       "addr.alt %1!load.s.pri %2!bounds %3!lidx.b %4!",
   711     #else
   712       "\364\316\327\302\341\342\355",
   713       "\365\316\366\367\335",
   714     #endif
   715     seqsize(8,4) - seqsize(4,4)
   716   },
   717   {
   718     #ifdef SCPACK
   719       "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!load.i!",
   720       "const.alt %1!load.s.pri %2!bounds %3!lidx.b %4!",
   721     #else
   722       "\363\316\327\302\341\342\355",
   723       "\376\316\366\367\335",
   724     #endif
   725     seqsize(8,4) - seqsize(4,4)
   726   },
   727   {
   728     #ifdef SCPACK
   729       "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!load.i!",
   730       "addr.alt %1!load.s.pri %2!lidx.b %3!",
   731     #else
   732       "\364\327\256\241\271\342\355",
   733       "\365\366\367\256",
   734     #endif
   735     seqsize(7,3) - seqsize(3,3)
   736   },
   737   {
   738     #ifdef SCPACK
   739       "const.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!load.i!",
   740       "const.alt %1!load.s.pri %2!lidx.b %3!",
   741     #else
   742       "\363\327\256\241\271\342\355",
   743       "\376\366\367\256",
   744     #endif
   745     seqsize(7,3) - seqsize(3,3)
   746   },
   747 #if !defined BIT16
   748   /* array index calculation for storing a value, "cell" aligned */
   749   {
   750     #ifdef SCPACK
   751       "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!",
   752       "addr.alt %1!load.s.pri %2!bounds %3!idxaddr!",
   753     #else
   754       "\364\316\370",
   755       "\365\316\322\235\237",
   756     #endif
   757     seqsize(7,4) - seqsize(4,3)
   758   },
   759   {
   760     #ifdef SCPACK
   761       "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri 2!pop.alt!add!",
   762       "const.alt %1!load.s.pri %2!bounds %3!idxaddr!",
   763     #else
   764       "\363\316\370",
   765       "\376\316\322\235\237",
   766     #endif
   767     seqsize(7,4) - seqsize(4,3)
   768   },
   769   {
   770     #ifdef SCPACK
   771       "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!",
   772       "addr.alt %1!load.s.pri %2!idxaddr!",
   773     #else
   774       "\364\370",
   775       "\365\322\235\237",
   776     #endif
   777     seqsize(6,3) - seqsize(3,2)
   778   },
   779   {
   780     #ifdef SCPACK
   781       "const.pri %1!push.pri!load.s.pri %2!shl.c.pri 2!pop.alt!add!",
   782       "const.alt %1!load.s.pri %2!idxaddr!",
   783     #else
   784       "\363\370",
   785       "\376\322\235\237",
   786     #endif
   787     seqsize(6,3) - seqsize(3,2)
   788   },
   789 #endif
   790   /* array index calculation for storing a value, not "cell" packed */
   791   {
   792     #ifdef SCPACK
   793       "addr.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!",
   794       "addr.alt %1!load.s.pri %2!bounds %3!idxaddr.b %4!",
   795     #else
   796       "\364\316\327\302\341",
   797       "\365\316\322\265\367\335",
   798     #endif
   799     seqsize(7,4) - seqsize(4,4)
   800   },
   801   {
   802     #ifdef SCPACK
   803       "const.pri %1!push.pri!load.s.pri %2!bounds %3!shl.c.pri %4!pop.alt!add!",
   804       "const.alt %1!load.s.pri %2!bounds %3!idxaddr.b %4!",
   805     #else
   806       "\363\316\327\302\341",
   807       "\376\316\322\265\367\335",
   808     #endif
   809     seqsize(7,4) - seqsize(4,4)
   810   },
   811   {
   812     #ifdef SCPACK
   813       "addr.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!",
   814       "addr.alt %1!load.s.pri %2!idxaddr.b %3!",
   815     #else
   816       "\364\327\256\241\271",
   817       "\365\322\265\367\256",
   818     #endif
   819     seqsize(6,3) - seqsize(3,3)
   820   },
   821   {
   822     #ifdef SCPACK
   823       "const.pri %1!push.pri!load.s.pri %2!shl.c.pri %3!pop.alt!add!",
   824       "const.alt %1!load.s.pri %2!idxaddr.b %3!",
   825     #else
   826       "\363\327\256\241\271",
   827       "\376\322\265\367\256",
   828     #endif
   829     seqsize(6,3) - seqsize(3,3)
   830   },
   831 #if !defined BIT16
   832   /* the shorter array indexing sequences, see above for comments */
   833   {
   834     #ifdef SCPACK
   835       "shl.c.pri 2!pop.alt!add!loadi!",
   836       "pop.alt!lidx!",
   837     #else
   838       "\370\217\355",
   839       "\241\366!",
   840     #endif
   841     seqsize(4,1) - seqsize(2,0)
   842   },
   843   {
   844     #ifdef SCPACK
   845       "shl.c.pri 2!pop.alt!add!",
   846       "pop.alt!idxaddr!",
   847     #else
   848       "\370",
   849       "\241\322\235\237",
   850     #endif
   851     seqsize(3,1) - seqsize(2,0)
   852   },
   853 #endif
   854   {
   855     #ifdef SCPACK
   856       "shl.c.pri %1!pop.alt!add!loadi!",
   857       "pop.alt!lidx.b %1!",
   858     #else
   859       "\314\225\241\271\217\355",
   860       "\241\366\367\202",
   861     #endif
   862     seqsize(4,1) - seqsize(2,1)
   863   },
   864   {
   865     #ifdef SCPACK
   866       "shl.c.pri %1!pop.alt!add!",
   867       "pop.alt!idxaddr.b %1!",
   868     #else
   869       "\314\225\241\271",
   870       "\241\322\265\367\202",
   871     #endif
   872     seqsize(3,1) - seqsize(2,1)
   873   },
   874   /* For packed arrays, there is another case (packed arrays
   875    * do not take advantage of the LIDX or IDXADDR instructions).
   876    *    addr.pri n1             addr.alt n1
   877    *    push.pri                load.s.pri n2
   878    *    load.s.pri n2           bounds n3
   879    *    bounds n3               -
   880    *    pop.alt                 -
   881    *
   882    * Notes (additional cases):
   883    * 1. instruction addr.pri can also be const.pri (for
   884    *    global arrays)
   885    * 2. the bounds instruction can be absent, but that
   886    *    case is already handled (see #1#)
   887    */
   888   {
   889     #ifdef SCPACK
   890       "addr.pri %1!push.pri!load.s.pri %2!bounds %3!pop.alt!",
   891       "addr.alt %1!load.s.pri %2!bounds %3!",
   892     #else
   893       "\364\316\241",
   894       "\365\316",
   895     #endif
   896     seqsize(5,3) - seqsize(3,3)
   897   },
   898   {
   899     #ifdef SCPACK
   900       "const.pri %1!push.pri!load.s.pri %2!bounds %3!pop.alt!",
   901       "const.alt %1!load.s.pri %2!bounds %3!",
   902     #else
   903       "\363\316\241",
   904       "\376\316",
   905     #endif
   906     seqsize(5,3) - seqsize(3,3)
   907   },
   908   /* Declaration of simple variables often follows the sequence:
   909    *    ;$lcl <name> <stk>      ;$lcl <name> <stk>
   910    *    stack -4                push.c <constval>
   911    *    const.pri <constval>    ;$exp
   912    *    stor.s.pri <stk>        -
   913    *    ;$exp                   -
   914    */
   915   {
   916     #ifdef SCPACK
   917       ";$lcl %1 %2!stack -4!const.pri %3!stor.s.pri %2!;$exp!",
   918       ";$lcl %1 %2!push.c %3!;$exp!",
   919     #else
   920       "\224lcl\332\227ack -4!\233\206\256\227or\222\230\252",
   921       "\224lcl\332\331\256\252",
   922     #endif
   923     seqsize(3,3) - seqsize(1,1)
   924   },
   925   {
   926     #ifdef SCPACK
   927       ";$lcl %1 %2!stack -4!zero.pri!stor.s.pri %2!;$exp!",
   928       ";$lcl %1 %2!push.c 0!;$exp!",
   929     #else
   930       "\224lcl\332\227ack -4!\373\227or\222\230\252",
   931       "\224lcl\332\331 0!\252",
   932     #endif
   933     seqsize(3,2) - seqsize(1,1)
   934   },
   935   /* During a calculation, the intermediate result must sometimes
   936    * be moved from PRI to ALT, like in:
   937    *    push.pri                move.alt
   938    *    load.s.pri n1           load.s.pri n1
   939    *    pop.alt                 -
   940    *
   941    * The above also accurs for "load.pri" and for "const.pri",
   942    * so add another two cases.
   943    */
   944   {
   945     #ifdef SCPACK
   946       "push.pri!load.s.pri %1!pop.alt!",
   947       "move.alt!load.s.pri %1!",
   948     #else
   949       "\244\333\241",
   950       "\306\333",
   951     #endif
   952     seqsize(3,1) - seqsize(2,1)
   953   },
   954   {
   955     #ifdef SCPACK
   956       "push.pri!load.pri %1!pop.alt!",
   957       "move.alt!load.pri %1!",
   958     #else
   959       "\244\311\241",
   960       "\306\311",
   961     #endif
   962     seqsize(3,1) - seqsize(2,1)
   963   },
   964   {
   965     #ifdef SCPACK
   966       "push.pri!const.pri %1!pop.alt!",
   967       "move.alt!const.pri %1!",
   968     #else
   969       "\244\330\241",
   970       "\306\330",
   971     #endif
   972     seqsize(3,1) - seqsize(2,1)
   973   },
   974   {
   975     #ifdef SCPACK
   976       "push.pri!zero.pri!pop.alt!",
   977       "move.alt!zero.pri!",
   978     #else
   979       "\244\373\241",
   980       "\306\373",
   981     #endif
   982     seqsize(3,0) - seqsize(2,0)
   983   },
   984   /* saving PRI and then loading from its address
   985    * occurs when indexing a multi-dimensional array
   986    */
   987   {
   988     #ifdef SCPACK
   989       "push.pri!load.i!pop.alt!",
   990       "move.alt!load.i!",
   991     #else
   992       "\244\342i\266",
   993       "\306\342\355",
   994     #endif
   995     seqsize(3,0) - seqsize(2,0)
   996   },
   997   /* An even simpler PUSH/POP optimization (occurs in
   998    * switch statements):
   999    *    push.pri                move.alt
  1000    *    pop.alt                 -
  1001    */
  1002   {
  1003     #ifdef SCPACK
  1004       "push.pri!pop.alt!",
  1005       "move.alt!",
  1006     #else
  1007       "\244\241",
  1008       "\306",
  1009     #endif
  1010     seqsize(2,0) - seqsize(1,0)
  1011   },
  1012   /* Some simple arithmetic sequences
  1013    */
  1014   {
  1015     #ifdef SCPACK
  1016       "move.alt!load.s.pri %1!add!",
  1017       "load.s.alt %1!add!",
  1018     #else
  1019       "\306\333\271",
  1020       "\375\271",
  1021     #endif
  1022     seqsize(3,1) - seqsize(2,1)
  1023   },
  1024   {
  1025     #ifdef SCPACK
  1026       "move.alt!load.pri %1!add!",
  1027       "load.alt %1!add!",
  1028     #else
  1029       "\306\311\271",
  1030       "\374\271",
  1031     #endif
  1032     seqsize(3,1) - seqsize(2,1)
  1033   },
  1034   {
  1035     #ifdef SCPACK
  1036       "move.alt!const.pri %1!add!",
  1037       "const.alt %1!add!",
  1038     #else
  1039       "\306\330\271",
  1040       "\356\271",
  1041     #endif
  1042     seqsize(3,1) - seqsize(2,1)
  1043   },
  1044   {
  1045     #ifdef SCPACK
  1046       "move.alt!load.s.pri %1!sub.alt!",
  1047       "load.s.alt %1!sub!",
  1048     #else
  1049       "\306\333sub\223",
  1050       "\375sub!",
  1051     #endif
  1052     seqsize(3,1) - seqsize(2,1)
  1053   },
  1054   {
  1055     #ifdef SCPACK
  1056       "move.alt!load.pri %1!sub.alt!",
  1057       "load.alt %1!sub!",
  1058     #else
  1059       "\306\311sub\223",
  1060       "\374sub!",
  1061     #endif
  1062     seqsize(3,1) - seqsize(2,1)
  1063   },
  1064   {
  1065     #ifdef SCPACK
  1066       "move.alt!const.pri %1!sub.alt!",
  1067       "const.alt %1!sub!",
  1068     #else
  1069       "\306\330sub\223",
  1070       "\356sub!",
  1071     #endif
  1072     seqsize(3,1) - seqsize(2,1)
  1073   },
  1074   /* User-defined operators first load the operands into registers and
  1075    * then have them pushed onto the stack. This can give rise to sequences
  1076    * like:
  1077    *    const.pri n1            push.c n1
  1078    *    const.alt n2            push.c n2
  1079    *    push.pri                -
  1080    *    push.alt                -
  1081    * A similar sequence occurs with the two PUSH.pri/alt instructions inverted.
  1082    * The first, second, or both CONST.pri/alt instructions can also be
  1083    * LOAD.pri/alt.
  1084    * This gives 2 x 4 cases.
  1085    */
  1086   {
  1087     #ifdef SCPACK
  1088       "const.pri %1!const.alt %2!push.pri!push.alt!",
  1089       "push.c %1!push.c %2!",
  1090     #else
  1091       "\330\233\304\244\354",
  1092       "\331\202\331\221",
  1093     #endif
  1094     seqsize(4,2) - seqsize(2,2)
  1095   },
  1096   {
  1097     #ifdef SCPACK
  1098       "const.pri %1!const.alt %2!push.alt!push.pri!",
  1099       "push.c %2!push.c %1!",
  1100     #else
  1101       "\330\233\304\354\244",
  1102       "\331\221\331\202",
  1103     #endif
  1104     seqsize(4,2) - seqsize(2,2)
  1105   },
  1106   {
  1107     #ifdef SCPACK
  1108       "const.pri %1!load.alt %2!push.pri!push.alt!",
  1109       "push.c %1!push %2!",
  1110     #else
  1111       "\330\362\244\354",
  1112       "\331\202\216\221",
  1113     #endif
  1114     seqsize(4,2) - seqsize(2,2)
  1115   },
  1116   {
  1117     #ifdef SCPACK
  1118       "const.pri %1!load.alt %2!push.alt!push.pri!",
  1119       "push %2!push.c %1!",
  1120     #else
  1121       "\330\362\354\244",
  1122       "\216\221\331\202",
  1123     #endif
  1124     seqsize(4,2) - seqsize(2,2)
  1125   },
  1126   {
  1127     #ifdef SCPACK
  1128       "load.pri %1!const.alt %2!push.pri!push.alt!",
  1129       "push %1!push.c %2!",
  1130     #else
  1131       "\311\233\304\244\354",
  1132       "\216\202\331\221",
  1133     #endif
  1134     seqsize(4,2) - seqsize(2,2)
  1135   },
  1136   {
  1137     #ifdef SCPACK
  1138       "load.pri %1!const.alt %2!push.alt!push.pri!",
  1139       "push.c %2!push %1!",
  1140     #else
  1141       "\311\233\304\354\244",
  1142       "\331\221\216\202",
  1143     #endif
  1144     seqsize(4,2) - seqsize(2,2)
  1145   },
  1146   {
  1147     #ifdef SCPACK
  1148       "load.pri %1!load.alt %2!push.pri!push.alt!",
  1149       "push %1!push %2!",
  1150     #else
  1151       "\311\362\244\354",
  1152       "\216\202\216\221",
  1153     #endif
  1154     seqsize(4,2) - seqsize(2,2)
  1155   },
  1156   {
  1157     #ifdef SCPACK
  1158       "load.pri %1!load.alt %2!push.alt!push.pri!",
  1159       "push %2!push %1!",
  1160     #else
  1161       "\311\362\354\244",
  1162       "\216\221\216\202",
  1163     #endif
  1164     seqsize(4,2) - seqsize(2,2)
  1165   },
  1166   /* Function calls (parameters are passed on the stack)
  1167    *    load.s.pri n1           push.s n1
  1168    *    push.pri                -
  1169    *    --------------------------------------
  1170    *    load.pri n1             push n1
  1171    *    push.pri                -
  1172    *    --------------------------------------
  1173    *    const.pri n1            push.c n1
  1174    *    push.pri                -
  1175    *    --------------------------------------
  1176    *    zero.pri                push.c 0
  1177    *    push.pri                -
  1178    *    --------------------------------------
  1179    *    addr.pri n1             push.adr n1
  1180    *    push.pri                -
  1181    *
  1182    * However, PRI must not be needed after this instruction
  1183    * if this shortcut is used. Check for the ;$par comment.
  1184    */
  1185   {
  1186     #ifdef SCPACK
  1187       "load.s.pri %1!push.pri!;$par!",
  1188       "push.s %1!;$par!",
  1189     #else
  1190       "\226\264\255",
  1191       "\216\222\202\255",
  1192     #endif
  1193     seqsize(2,1) - seqsize(1,1)
  1194   },
  1195   {
  1196     #ifdef SCPACK
  1197       "load.pri %1!push.pri!;$par!",
  1198       "push %1!;$par!",
  1199     #else
  1200       "\217\264\255",
  1201       "\216\202\255",
  1202     #endif
  1203     seqsize(2,1) - seqsize(1,1)
  1204   },
  1205   {
  1206     #ifdef SCPACK
  1207       "const.pri %1!push.pri!;$par!",
  1208       "push.c %1!;$par!",
  1209     #else
  1210       "\233\264\255",
  1211       "\331\202\255",
  1212     #endif
  1213     seqsize(2,1) - seqsize(1,1)
  1214   },
  1215   {
  1216     #ifdef SCPACK
  1217       "zero.pri!push.pri!;$par!",
  1218       "push.c 0!;$par!",
  1219     #else
  1220       "\373\244\255",
  1221       "\331 0!\255",
  1222     #endif
  1223     seqsize(2,0) - seqsize(1,1)
  1224   },
  1225   {
  1226     #ifdef SCPACK
  1227       "addr.pri %1!push.pri!;$par!",
  1228       "push.adr %1!;$par!",
  1229     #else
  1230       "\265\264\255",
  1231       "\216\326\202\255",
  1232     #endif
  1233     seqsize(2,1) - seqsize(1,1)
  1234   },
  1235   /* References with a default value generate new cells on the heap
  1236    * dynamically. That code often ends with:
  1237    *    move.pri                push.alt
  1238    *    push.pri                -
  1239    */
  1240   {
  1241     #ifdef SCPACK
  1242       "move.pri!push.pri!",
  1243       "push.alt!",
  1244     #else
  1245       "\300\236\244",
  1246       "\354",
  1247     #endif
  1248     seqsize(2,0) - seqsize(1,0)
  1249   },
  1250   /* Simple arithmetic operations on constants. Noteworthy is the
  1251    * subtraction of a constant, since it is converted to the addition
  1252    * of the inverse value.
  1253    *    const.alt n1            add.c n1
  1254    *    add                     -
  1255    *    --------------------------------------
  1256    *    const.alt n1            add.c -n1
  1257    *    sub                     -
  1258    *    --------------------------------------
  1259    *    const.alt n1            smul.c n1
  1260    *    smul                    -
  1261    *    --------------------------------------
  1262    *    const.alt n1            eq.c.pri n1
  1263    *    eq                      -
  1264    */
  1265   {
  1266     #ifdef SCPACK
  1267       "const.alt %1!add!",
  1268       "add.c %1!",
  1269     #else
  1270       "\356\271",
  1271       "\235\242\202",
  1272     #endif
  1273     seqsize(2,1) - seqsize(1,1)
  1274   },
  1275   {
  1276     #ifdef SCPACK
  1277       "const.alt %1!sub!",
  1278       "add.c -%1!",
  1279     #else
  1280       "\356sub!",
  1281       "\235\242 -\201",
  1282     #endif
  1283     seqsize(2,1) - seqsize(1,1)
  1284   },
  1285   {
  1286     #ifdef SCPACK
  1287       "const.alt %1!smul!",
  1288       "smul.c %1!",
  1289     #else
  1290       "\356smul!",
  1291       "smu\307\202",
  1292     #endif
  1293     seqsize(2,1) - seqsize(1,1)
  1294   },
  1295   {
  1296     #ifdef SCPACK
  1297       "const.alt %1!eq!",
  1298       "eq.c.pri %1!",
  1299     #else
  1300       "\356\325",
  1301       "\262\242\225",
  1302     #endif
  1303     seqsize(2,1) - seqsize(1,1)
  1304   },
  1305   /* Some operations use the alternative subtraction operation --these
  1306    * can also be optimized.
  1307    *    const.pri n1            load.s.pri n2
  1308    *    load.s.alt n2           add.c -n1
  1309    *    sub.alt                 -
  1310    *    --------------------------------------
  1311    *    const.pri n1            load.pri n2
  1312    *    load.alt n2             add.c -n1
  1313    *    sub.alt                 -
  1314    */
  1315   {
  1316     #ifdef SCPACK
  1317       "const.pri %1!load.s.alt %2!sub.alt!",
  1318       "load.s.pri %2!add.c -%1!",
  1319     #else
  1320       "\330\226\304sub\223",
  1321       "\246\235\242 -\201",
  1322     #endif
  1323     seqsize(3,2) - seqsize(2,2)
  1324   },
  1325   {
  1326     #ifdef SCPACK
  1327       "const.pri %1!load.alt %2!sub.alt!",
  1328       "load.pri %2!add.c -%1!",
  1329     #else
  1330       "\330\362sub\223",
  1331       "\334\235\242 -\201",
  1332     #endif
  1333     seqsize(3,2) - seqsize(2,2)
  1334   },
  1335   /* With arrays indexed with constants that come from enumerations, it happens
  1336    * multiple add.c opcodes follow in sequence.
  1337    *    add.c n1                add.c n1+n2
  1338    *    add.c n2                -
  1339    */
  1340   {
  1341     #ifdef SCPACK
  1342       "add.c %1!add.c %2!",
  1343       "add.c %1+%2!",
  1344     #else
  1345       "\235\242\202\235\242\221",
  1346       "\235\242\267+%2!",
  1347     #endif
  1348     seqsize(2,2) - seqsize(1,1)
  1349   },
  1350   /* Compare and jump
  1351    *    eq                      jneq n1
  1352    *    jzer n1                 -
  1353    *    --------------------------------------
  1354    *    eq                      jeq n1
  1355    *    jnz n1                  -
  1356    *    --------------------------------------
  1357    *    neq                     jeq n1
  1358    *    jzer n1                 -
  1359    *    --------------------------------------
  1360    *    neq                     jneq n1
  1361    *    jnz n1                  -
  1362    * Compares followed by jzer occur much more
  1363    * often than compares followed with jnz. So we
  1364    * take the easy route here.
  1365    *    less                    jgeq n1
  1366    *    jzer n1                 -
  1367    *    --------------------------------------
  1368    *    leq                     jgrtr n1
  1369    *    jzer n1                 -
  1370    *    --------------------------------------
  1371    *    grtr                    jleq n1
  1372    *    jzer n1                 -
  1373    *    --------------------------------------
  1374    *    geq                     jless n1
  1375    *    jzer n1                 -
  1376    *    --------------------------------------
  1377    *    sless                   jsgeq n1
  1378    *    jzer n1                 -
  1379    *    --------------------------------------
  1380    *    sleq                    jsgrtr n1
  1381    *    jzer n1                 -
  1382    *    --------------------------------------
  1383    *    sgrtr                   jsleq n1
  1384    *    jzer n1                 -
  1385    *    --------------------------------------
  1386    *    sgeq                    jsless n1
  1387    *    jzer n1                 -
  1388    */
  1389   {
  1390     #ifdef SCPACK
  1391       "eq!jzer %1!",
  1392       "jneq %1!",
  1393     #else
  1394       "\325\323",
  1395       "jn\357",
  1396     #endif
  1397     seqsize(2,1) - seqsize(1,1)
  1398   },
  1399   {
  1400     #ifdef SCPACK
  1401       "eq!jnz %1!",
  1402       "jeq %1!",
  1403     #else
  1404       "\325jnz\202",
  1405       "j\357",
  1406     #endif
  1407     seqsize(2,1) - seqsize(1,1)
  1408   },
  1409   {
  1410     #ifdef SCPACK
  1411       "neq!jzer %1!",
  1412       "jeq %1!",
  1413     #else
  1414       "n\325\323",
  1415       "j\357",
  1416     #endif
  1417     seqsize(2,1) - seqsize(1,1)
  1418   },
  1419   {
  1420     #ifdef SCPACK
  1421       "neq!jnz %1!",
  1422       "jneq %1!",
  1423     #else
  1424       "n\325jnz\202",
  1425       "jn\357",
  1426     #endif
  1427     seqsize(2,1) - seqsize(1,1)
  1428   },
  1429   {
  1430     #ifdef SCPACK
  1431       "less!jzer %1!",
  1432       "jgeq %1!",
  1433     #else
  1434       "l\352!\323",
  1435       "jg\357",
  1436     #endif
  1437     seqsize(2,1) - seqsize(1,1)
  1438   },
  1439   {
  1440     #ifdef SCPACK
  1441       "leq!jzer %1!",
  1442       "jgrtr %1!",
  1443     #else
  1444       "l\325\323",
  1445       "jg\353r\202",
  1446     #endif
  1447     seqsize(2,1) - seqsize(1,1)
  1448   },
  1449   {
  1450     #ifdef SCPACK
  1451       "grtr!jzer %1!",
  1452       "jleq %1!",
  1453     #else
  1454       "g\353\237\323",
  1455       "jl\357",
  1456     #endif
  1457     seqsize(2,1) - seqsize(1,1)
  1458   },
  1459   {
  1460     #ifdef SCPACK
  1461       "geq!jzer %1!",
  1462       "jless %1!",
  1463     #else
  1464       "g\325\323",
  1465       "jl\352\202",
  1466     #endif
  1467     seqsize(2,1) - seqsize(1,1)
  1468   },
  1469   {
  1470     #ifdef SCPACK
  1471       "sless!jzer %1!",
  1472       "jsgeq %1!",
  1473     #else
  1474       "\372!\323",
  1475       "j\320\357",
  1476     #endif
  1477     seqsize(2,1) - seqsize(1,1)
  1478   },
  1479   {
  1480     #ifdef SCPACK
  1481       "sleq!jzer %1!",
  1482       "jsgrtr %1!",
  1483     #else
  1484       "\321\325\323",
  1485       "j\371r\202",
  1486     #endif
  1487     seqsize(2,1) - seqsize(1,1)
  1488   },
  1489   {
  1490     #ifdef SCPACK
  1491       "sgrtr!jzer %1!",
  1492       "jsleq %1!",
  1493     #else
  1494       "\371\237\323",
  1495       "j\321\357",
  1496     #endif
  1497     seqsize(2,1) - seqsize(1,1)
  1498   },
  1499   {
  1500     #ifdef SCPACK
  1501       "sgeq!jzer %1!",
  1502       "jsless %1!",
  1503     #else
  1504       "\320\325\323",
  1505       "j\372\202",
  1506     #endif
  1507     seqsize(2,1) - seqsize(1,1)
  1508   },
  1509   /* Test for zero (common case, especially for strings)
  1510    * E.g. the test expression of: "for (i=0; str{i}!=0; ++i)"
  1511    *
  1512    *    zero.alt                jzer n1
  1513    *    jeq n1                  -
  1514    *    --------------------------------------
  1515    *    zero.alt                jnz n1
  1516    *    jneq n1                 -
  1517    */
  1518   {
  1519     #ifdef SCPACK
  1520       "zero.alt!jeq %1!",
  1521       "jzer %1!",
  1522     #else
  1523       "\340\223j\357",
  1524       "\323",
  1525     #endif
  1526     seqsize(2,1) - seqsize(1,1)
  1527   },
  1528   {
  1529     #ifdef SCPACK
  1530       "zero.alt!jneq %1!",
  1531       "jnz %1!",
  1532     #else
  1533       "\340\223jn\357",
  1534       "jnz\202",
  1535     #endif
  1536     seqsize(2,1) - seqsize(1,1)
  1537   },
  1538   /* Incrementing and decrementing leaves a value in
  1539    * in PRI which may not be used (for example, as the
  1540    * third expression in a "for" loop).
  1541    *    inc n1                  inc n1  ; ++n
  1542    *    load.pri n1             ;$exp
  1543    *    ;$exp                   -
  1544    *    --------------------------------------
  1545    *    load.pri n1             inc n1  ; n++, e.g. "for (n=0; n<10; n++)"
  1546    *    inc n1                  ;$exp
  1547    *    ;$exp                   -
  1548    * Plus the varieties for stack relative increments
  1549    * and decrements.
  1550    */
  1551   {
  1552     #ifdef SCPACK
  1553       "inc %1!load.pri %1!;$exp!",
  1554       "inc %1!;$exp!",
  1555     #else
  1556       "inc\202\311\252",
  1557       "inc\301",
  1558     #endif
  1559     seqsize(2,2) - seqsize(1,1)
  1560   },
  1561   {
  1562     #ifdef SCPACK
  1563       "load.pri %1!inc %1!;$exp!",
  1564       "inc %1!;$exp!",
  1565     #else
  1566       "\311inc\301",
  1567       "inc\301",
  1568     #endif
  1569     seqsize(2,2) - seqsize(1,1)
  1570   },
  1571   {
  1572     #ifdef SCPACK
  1573       "inc.s %1!load.s.pri %1!;$exp!",
  1574       "inc.s %1!;$exp!",
  1575     #else
  1576       "inc\222\202\333\252",
  1577       "inc\222\301",
  1578     #endif
  1579     seqsize(2,2) - seqsize(1,1)
  1580   },
  1581   {
  1582     #ifdef SCPACK
  1583       "load.s.pri %1!inc.s %1!;$exp!",
  1584       "inc.s %1!;$exp!",
  1585     #else
  1586       "\333inc\222\301",
  1587       "inc\222\301",
  1588     #endif
  1589     seqsize(2,2) - seqsize(1,1)
  1590   },
  1591   {
  1592     #ifdef SCPACK
  1593       "dec %1!load.pri %1!;$exp!",
  1594       "dec %1!;$exp!",
  1595     #else
  1596       "dec\202\311\252",
  1597       "dec\301",
  1598     #endif
  1599     seqsize(2,2) - seqsize(1,1)
  1600   },
  1601   {
  1602     #ifdef SCPACK
  1603       "load.pri %1!dec %1!;$exp!",
  1604       "dec %1!;$exp!",
  1605     #else
  1606       "\311dec\301",
  1607       "dec\301",
  1608     #endif
  1609     seqsize(2,2) - seqsize(1,1)
  1610   },
  1611   {
  1612     #ifdef SCPACK
  1613       "dec.s %1!load.s.pri %1!;$exp!",
  1614       "dec.s %1!;$exp!",
  1615     #else
  1616       "dec\222\202\333\252",
  1617       "dec\222\301",
  1618     #endif
  1619     seqsize(2,2) - seqsize(1,1)
  1620   },
  1621   {
  1622     #ifdef SCPACK
  1623       "load.s.pri %1!dec.s %1!;$exp!",
  1624       "dec.s %1!;$exp!",
  1625     #else
  1626       "\333dec\222\301",
  1627       "dec\222\301",
  1628     #endif
  1629     seqsize(2,2) - seqsize(1,1)
  1630   },
  1631   /* ??? the same (increments and decrements) for references */
  1632   /* Loading the constant zero has a special opcode.
  1633    * When storing zero in memory, the value of PRI must not be later on.
  1634    *    const.pri 0             zero n1
  1635    *    stor.pri n1             ;$exp
  1636    *    ;$exp                   -
  1637    *    --------------------------------------
  1638    *    const.pri 0             zero.s n1
  1639    *    stor.s.pri n1           ;$exp
  1640    *    ;$exp                   -
  1641    *    --------------------------------------
  1642    *    zero.pri                zero n1
  1643    *    stor.pri n1             ;$exp
  1644    *    ;$exp                   -
  1645    *    --------------------------------------
  1646    *    zero.pri                zero.s n1
  1647    *    stor.s.pri n1           ;$exp
  1648    *    ;$exp                   -
  1649    *    --------------------------------------
  1650    *    const.pri 0             zero.pri
  1651    *    --------------------------------------
  1652    *    const.alt 0             zero.alt
  1653    * The last two alternatives save more memory than they save
  1654    * time, but anyway...
  1655    */
  1656   {
  1657     #ifdef SCPACK
  1658       "const.pri 0!stor.pri %1!;$exp!",
  1659       "zero %1!;$exp!",
  1660     #else
  1661       "\233\206 0!\227or\225\252",
  1662       "\340\301",
  1663     #endif
  1664     seqsize(2,2) - seqsize(1,1)
  1665   },
  1666   {
  1667     #ifdef SCPACK
  1668       "const.pri 0!stor.s.pri %1!;$exp!",
  1669       "zero.s %1!;$exp!",
  1670     #else
  1671       "\233\206 0!\227or\222\225\252",
  1672       "\340\222\301",
  1673     #endif
  1674     seqsize(2,2) - seqsize(1,1)
  1675   },
  1676   {
  1677     #ifdef SCPACK
  1678       "zero.pri!stor.pri %1!;$exp!",
  1679       "zero %1!;$exp!",
  1680     #else
  1681       "\373\227or\225\252",
  1682       "\340\301",
  1683     #endif
  1684     seqsize(2,1) - seqsize(1,1)
  1685   },
  1686   {
  1687     #ifdef SCPACK
  1688       "zero.pri!stor.s.pri %1!;$exp!",
  1689       "zero.s %1!;$exp!",
  1690     #else
  1691       "\373\227or\222\225\252",
  1692       "\340\222\301",
  1693     #endif
  1694     seqsize(2,1) - seqsize(1,1)
  1695   },
  1696   {
  1697     #ifdef SCPACK
  1698       "const.pri 0!",
  1699       "zero.pri!",
  1700     #else
  1701       "\233\206 0!",
  1702       "\373",
  1703     #endif
  1704     seqsize(1,1) - seqsize(1,0)
  1705   },
  1706   {
  1707     #ifdef SCPACK
  1708       "const.alt 0!",
  1709       "zero.alt!",
  1710     #else
  1711       "\233\212 0!",
  1712       "\340\223",
  1713     #endif
  1714     seqsize(1,1) - seqsize(1,0)
  1715   },
  1716 
  1717   /* ------------------ */
  1718   /* Macro instructions */
  1719   /* ------------------ */
  1720 
  1721   { "", "", 0 },    /* separator, so optimizer can stop before generating macro opcodes */
  1722 
  1723   /* optimizing the calling of native functions (which always have a parameter
  1724    * count pushed before, and the stack pointer restored afterwards
  1725    */
  1726   {
  1727     #ifdef SCPACK
  1728       "push.c %1!sysreq.c %2!stack %3!",        //note: %3 == %1 + 4
  1729       "sysreq.n %2 %1!",
  1730     #else
  1731       "\331\202sysr\262\242\221\227ack\256",
  1732       "sysr\262.n\220\202",
  1733     #endif
  1734     seqsize(3,3) - seqsize(1,2)
  1735   },
  1736   /* ----- */
  1737   /* Functions with many parameters with the same "type" have sequences like:
  1738    *    push.c n1               push3.c n1 n2 n3
  1739    *    ;$par                   ;$par
  1740    *    push.c n2               -
  1741    *    ;$par                   -
  1742    *    push.c n3               -
  1743    *    ;$par                   -
  1744    *    etc.                    etc.
  1745    *
  1746    * Similar sequences occur with PUSH, PUSH.s and PUSHADDR
  1747    */
  1748   {
  1749     #ifdef SCPACK
  1750       "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!push.c %4!;$par!push.c %5!",
  1751       "push5.c %1 %2 %3 %4 %5!",
  1752     #else
  1753       "\331\336\242\345\242\256\257\242\335\257\242\2035!",
  1754       "\2165\242\343\245\302\2035!",
  1755     #endif
  1756     seqsize(5,5) - seqsize(1,5)
  1757   },
  1758   {
  1759     #ifdef SCPACK
  1760       "push.c %1!;$par!push.c %2!;$par!push.c %3!;$par!push.c %4!",
  1761       "push4.c %1 %2 %3 %4!",
  1762     #else
  1763       "\331\336\242\345\242\256\257\242\335",
  1764       "\2164\242\343\245\335",
  1765     #endif
  1766     seqsize(4,4) - seqsize(1,4)
  1767   },
  1768   {
  1769     #ifdef SCPACK
  1770       "push.c %1!;$par!push.c %2!;$par!push.c %3!",
  1771       "push3.c %1 %2 %3!",
  1772     #else
  1773       "\331\336\242\345\242\256",
  1774       "\2163\242\343\256",
  1775     #endif
  1776     seqsize(3,3) - seqsize(1,3)
  1777   },
  1778   {
  1779     #ifdef SCPACK
  1780       "push.c %1!;$par!push.c %2!",
  1781       "push2.c %1 %2!",
  1782     #else
  1783       "\331\336\242\221",
  1784       "\2162\242\332",
  1785     #endif
  1786     seqsize(2,2) - seqsize(1,2)
  1787   },
  1788   /* ----- */
  1789   {
  1790     #ifdef SCPACK
  1791       "push %1!;$par!push %2!;$par!push %3!;$par!push %4!;$par!push %5!",
  1792       "push5 %1 %2 %3 %4 %5!",
  1793     #else
  1794       "\216\336\345\256\257\335\257\2035!",
  1795       "\2165\343\245\302\2035!",
  1796     #endif
  1797     seqsize(5,5) - seqsize(1,5)
  1798   },
  1799   {
  1800     #ifdef SCPACK
  1801       "push %1!;$par!push %2!;$par!push %3!;$par!push %4!",
  1802       "push4 %1 %2 %3 %4!",
  1803     #else
  1804       "\216\336\345\256\257\335",
  1805       "\2164\343\245\335",
  1806     #endif
  1807     seqsize(4,4) - seqsize(1,4)
  1808   },
  1809   {
  1810     #ifdef SCPACK
  1811       "push %1!;$par!push %2!;$par!push %3!",
  1812       "push3 %1 %2 %3!",
  1813     #else
  1814       "\216\336\345\256",
  1815       "\2163\343\256",
  1816     #endif
  1817     seqsize(3,3) - seqsize(1,3)
  1818   },
  1819   {
  1820     #ifdef SCPACK
  1821       "push %1!;$par!push %2!",
  1822       "push2 %1 %2!",
  1823     #else
  1824       "\216\336\221",
  1825       "\2162\332",
  1826     #endif
  1827     seqsize(2,2) - seqsize(1,2)
  1828   },
  1829   /* ----- */
  1830   {
  1831     #ifdef SCPACK
  1832       "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!push.s %4!;$par!push.s %5!",
  1833       "push5.s %1 %2 %3 %4 %5!",
  1834     #else
  1835       "\216\222\336\222\345\222\256\257\222\335\257\222\2035!",
  1836       "\2165\222\343\245\302\2035!",
  1837     #endif
  1838     seqsize(5,5) - seqsize(1,5)
  1839   },
  1840   {
  1841     #ifdef SCPACK
  1842       "push.s %1!;$par!push.s %2!;$par!push.s %3!;$par!push.s %4!",
  1843       "push4.s %1 %2 %3 %4!",
  1844     #else
  1845       "\216\222\336\222\345\222\256\257\222\335",
  1846       "\2164\222\343\245\335",
  1847     #endif
  1848     seqsize(4,4) - seqsize(1,4)
  1849   },
  1850   {
  1851     #ifdef SCPACK
  1852       "push.s %1!;$par!push.s %2!;$par!push.s %3!",
  1853       "push3.s %1 %2 %3!",
  1854     #else
  1855       "\216\222\336\222\345\222\256",
  1856       "\2163\222\343\256",
  1857     #endif
  1858     seqsize(3,3) - seqsize(1,3)
  1859   },
  1860   {
  1861     #ifdef SCPACK
  1862       "push.s %1!;$par!push.s %2!",
  1863       "push2.s %1 %2!",
  1864     #else
  1865       "\216\222\336\222\221",
  1866       "\2162\222\332",
  1867     #endif
  1868     seqsize(2,2) - seqsize(1,2)
  1869   },
  1870   /* ----- */
  1871   {
  1872     #ifdef SCPACK
  1873       "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!push.adr %4!;$par!push.adr %5!",
  1874       "push5.adr %1 %2 %3 %4 %5!",
  1875     #else
  1876       "\216\326\336\326\345\326\256\257\326\335\257\326\2035!",
  1877       "\2165\326\343\245\302\2035!",
  1878     #endif
  1879     seqsize(5,5) - seqsize(1,5)
  1880   },
  1881   {
  1882     #ifdef SCPACK
  1883       "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!;$par!push.adr %4!",
  1884       "push4.adr %1 %2 %3 %4!",
  1885     #else
  1886       "\216\326\336\326\345\326\256\257\326\335",
  1887       "\2164\326\343\245\335",
  1888     #endif
  1889     seqsize(4,4) - seqsize(1,4)
  1890   },
  1891   {
  1892     #ifdef SCPACK
  1893       "push.adr %1!;$par!push.adr %2!;$par!push.adr %3!",
  1894       "push3.adr %1 %2 %3!",
  1895     #else
  1896       "\216\326\336\326\345\326\256",
  1897       "\2163\326\343\256",
  1898     #endif
  1899     seqsize(3,3) - seqsize(1,3)
  1900   },
  1901   {
  1902     #ifdef SCPACK
  1903       "push.adr %1!;$par!push.adr %2!",
  1904       "push2.adr %1 %2!",
  1905     #else
  1906       "\216\326\336\326\221",
  1907       "\2162\326\332",
  1908     #endif
  1909     seqsize(2,2) - seqsize(1,2)
  1910   },
  1911   /* Loading two registers at a time
  1912    *    load.pri n1             load.both n1 n2
  1913    *    load.alt n2             -
  1914    *    --------------------------------------
  1915    *    load.alt n2             load.both n1 n2
  1916    *    load.pri n1             -
  1917    *    --------------------------------------
  1918    *    load.s.pri n1           load.s.both n1 n2
  1919    *    load.s.alt n2           -
  1920    *    --------------------------------------
  1921    *    load.s.alt n2           load.s.both n1 n2
  1922    *    load.s.pri n1           -
  1923    */
  1924   {
  1925     #ifdef SCPACK
  1926       "load.pri %1!load.alt %2!",
  1927       "load.both %1 %2!",
  1928     #else
  1929       "\311\362",
  1930       "\342\275th\332",
  1931     #endif
  1932     seqsize(2,2) - seqsize(1,2)
  1933   },
  1934   {
  1935     #ifdef SCPACK
  1936       "load.alt %2!load.pri %1!",
  1937       "load.both %1 %2!",
  1938     #else
  1939       "\362\311",
  1940       "\342\275th\332",
  1941     #endif
  1942     seqsize(2,2) - seqsize(1,2)
  1943   },
  1944   {
  1945     #ifdef SCPACK
  1946       "load.s.pri %1!load.s.alt %2!",
  1947       "load.s.both %1 %2!",
  1948     #else
  1949       "\333\226\304",
  1950       "\226.\275th\332",
  1951     #endif
  1952     seqsize(2,2) - seqsize(1,2)
  1953   },
  1954   {
  1955     #ifdef SCPACK
  1956       "load.s.alt %2!load.s.pri %1!",
  1957       "load.s.both %1 %2!",
  1958     #else
  1959       "\226\304\333",
  1960       "\226.\275th\332",
  1961     #endif
  1962     seqsize(2,2) - seqsize(1,2)
  1963   },
  1964   /* Loading two registers and then pushing them occurs with user operators
  1965    *    load.both n1 n2         push2 n1 n2
  1966    *    push.pri                -
  1967    *    push.alt                -
  1968    *    --------------------------------------
  1969    *    load.s.both n1 n2       push2.s n1 n2
  1970    *    push.pri                -
  1971    *    push.alt                -
  1972    */
  1973   {
  1974     #ifdef SCPACK
  1975       "load.both %1 %2!push.pri!push.alt!",
  1976       "push2 %1 %2!",
  1977     #else
  1978       "\342\275th\332\244\354",
  1979       "\2162\332",
  1980     #endif
  1981     seqsize(3,2) - seqsize(1,2)
  1982   },
  1983   {
  1984     #ifdef SCPACK
  1985       "load.s.both %1 %2!push.pri!push.alt!",
  1986       "push2.s %1 %2!",
  1987     #else
  1988       "\226.\275th\332\244\354",
  1989       "\2162\222\332",
  1990     #endif
  1991     seqsize(3,2) - seqsize(1,2)
  1992   },
  1993   /* Load a constant in a variable
  1994    *    const.pri n1            const n2 n1
  1995    *    stor.pri n2             -
  1996    *    --------------------------------------
  1997    *    const.pri n1            const.s n2 n1
  1998    *    stor.s.pri n2           -
  1999    */
  2000   {
  2001     #ifdef SCPACK
  2002       "const.pri %1!stor.pri %2!",
  2003       "const %2 %1!",
  2004     #else
  2005       "\330\227or\230",
  2006       "\233\220\202",
  2007     #endif
  2008     seqsize(2,2) - seqsize(1,2)
  2009   },
  2010   {
  2011     #ifdef SCPACK
  2012       "const.pri %1!stor.s.pri %2!",
  2013       "const.s %2 %1!",
  2014     #else
  2015       "\330\227or\222\230",
  2016       "\233\222\220\202",
  2017     #endif
  2018     seqsize(2,2) - seqsize(1,2)
  2019   },
  2020   /* ----- */
  2021   { NULL, NULL, 0 }
  2022 };