PageRenderTime 6ms CodeModel.GetById 3ms app.highlight 263ms RepoModel.GetById 1ms app.codeStats 0ms

/misc/pascal/insn16/popt/pcopt.c

https://github.com/markangelo/PX4NuttX
C | 906 lines | 735 code | 106 blank | 65 comment | 218 complexity | 7e89157bc965a85525cc05c8799d2ae9 MD5 | raw file
  1/**********************************************************************
  2 * pcopt.c
  3 * Constant Expression Optimizations
  4 *
  5 *   Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
  6 *   Author: Gregory Nutt <gnutt@nuttx.org>
  7 *
  8 * Redistribution and use in source and binary forms, with or without
  9 * modification, are permitted provided that the following conditions
 10 * are met:
 11 *
 12 * 1. Redistributions of source code must retain the above copyright
 13 *    notice, this list of conditions and the following disclaimer.
 14 * 2. Redistributions in binary form must reproduce the above copyright
 15 *    notice, this list of conditions and the following disclaimer in
 16 *    the documentation and/or other materials provided with the
 17 *    distribution.
 18 * 3. Neither the name NuttX nor the names of its contributors may be
 19 *    used to endorse or promote products derived from this software
 20 *    without specific prior written permission.
 21 *
 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 33 * POSSIBILITY OF SUCH DAMAGE.
 34 *
 35 **********************************************************************/
 36
 37/**********************************************************************
 38 * Included Files
 39 **********************************************************************/
 40
 41#include <stdint.h>
 42#include <stdio.h>
 43
 44#include "keywords.h"
 45#include "pdefs.h"
 46#include "pinsn16.h"
 47
 48#include "paslib.h"
 49#include "popt.h"
 50#include "polocal.h"
 51#include "pcopt.h"
 52
 53/**********************************************************************/
 54
 55int16_t unaryOptimize(void)
 56{
 57  int16_t nchanges = 0;
 58  register uint16_t temp;
 59  register int16_t i;
 60
 61  TRACE(stderr, "[unaryOptimize]");
 62
 63  /* At least two pcodes are need to perform unary optimizations */
 64
 65   i = 0;
 66   while (i < nops-1)
 67     {
 68       /* Check for a constant value being pushed onto the stack */
 69
 70       if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB))
 71         {
 72           /* Turn the oPUSHB into an oPUSH op (temporarily) */
 73
 74           if (pptr[i]->op == oPUSHB)
 75             {
 76               pptr[i]->op   = oPUSH;
 77               pptr[i]->arg2 = pptr[i]->arg1;
 78               pptr[i]->arg1 = 0;
 79             } /* end if */
 80
 81           switch (pptr[i+1]->op)
 82             {
 83               /* Delete unary operators on constants */
 84             case oNEG   :
 85               pptr[i]->arg2 = -(pptr[i]->arg2);
 86               deletePcode(i+1);
 87               nchanges++;
 88               break;
 89
 90             case oABS   :
 91               if (signExtend16(pptr[i]->arg2) < 0)
 92                 pptr[i]->arg2 = -signExtend16(pptr[i]->arg2);
 93               deletePcode(i+1);
 94               nchanges++;
 95               break;
 96
 97             case oINC   :
 98               (pptr[i]->arg2)++;
 99               deletePcode(i+1);
100               nchanges++;
101               break;
102
103             case oDEC   :
104               (pptr[i]->arg2)--;
105               deletePcode(i+1);
106               nchanges++;
107               break;
108
109             case oNOT   :
110               pptr[i]->arg2 = ~(pptr[i]->arg2);
111               deletePcode(i+1);
112               nchanges++;
113               break;
114
115               /* Simplify binary operations on constants */
116
117             case oADD :
118               if (pptr[i]->arg2 == 0)
119                 {
120                   deletePcodePair(i, (i+1));
121                   nchanges++;
122                 } /* end if */
123               else if (pptr[i]->arg2 == 1)
124                 {
125                   pptr[i+1]->op = oINC;
126                   deletePcode(i);
127                   nchanges++;
128                 } /* end else if */
129               else if (pptr[i]->arg2 == (uint16_t)-1)
130                 {
131                   pptr[i+1]->op = oDEC;
132                   deletePcode(i);
133                   nchanges++;
134                 } /* end else if */
135               else i++;
136               break;
137
138             case oSUB :
139               if (pptr[i]->arg2 == 0)
140                 {
141                   deletePcodePair(i, (i+1));
142                   nchanges++;
143                 } /* end if */
144               else if (pptr[i]->arg2 == 1)
145                 {
146                   pptr[i+1]->op = oDEC;
147                   deletePcode(i);
148                   nchanges++;
149                 } /* end else if */
150               else if (pptr[i]->arg2 == (uint16_t)-1)
151                 {
152                   pptr[i+1]->op = oINC;
153                   deletePcode(i);
154                   nchanges++;
155                 } /* end else if */
156               else i++;
157               break;
158
159             case oMUL :
160             case oDIV :
161               temp = 0;
162               switch (pptr[i]->arg2)
163                 {
164                 case 1 :
165                   deletePcodePair(i, (i+1));
166                   nchanges++;
167                   break;
168                 case 16384 : temp++;
169                 case  8192 : temp++;
170                 case  4096 : temp++;
171                 case  2048 : temp++;
172                 case  1024 : temp++;
173                 case   512 : temp++;
174                 case   256 : temp++;
175                 case   128 : temp++;
176                 case    64 : temp++;
177                 case    32 : temp++;
178                 case    16 : temp++;
179                 case     8 : temp++;
180                 case     4 : temp++;
181                 case     2 : temp++;
182                   pptr[i]->arg2 = temp;
183                   if (pptr[i+1]->op == oMUL)
184                     pptr[i+1]->op = oSLL;
185                   else
186                     pptr[i+1]->op = oSRA;
187                   nchanges++;
188                   i++;
189                   break;
190
191                 default :
192                   i++;
193                   break;
194                 } /* end switch */
195               break;
196
197             case oSLL :
198             case oSRL :
199             case oSRA :
200             case oOR  :
201               if (pptr[i]->arg2 == 0)
202                 {
203                   deletePcodePair(i, (i+1));
204                   nchanges++;
205                 } /* end if */
206               else i++;
207               break;
208
209             case oAND :
210               if (pptr[i]->arg2 == 0xffff)
211                 {
212                   deletePcodePair(i, (i+1));
213                   nchanges++;
214                 } /* end if */
215               else i++;
216               break;
217
218               /* Delete comparisons of constants to zero */
219
220             case oEQUZ  :
221               if (pptr[i]->arg2 == 0) pptr[i]->arg2 = -1;
222               else pptr[i]->arg2 = 0;
223               deletePcode(i+1);
224               nchanges++;
225               break;
226
227             case oNEQZ  :
228               if (pptr[i]->arg2 != 0)
229                 pptr[i]->arg2 = -1;
230               else
231                 pptr[i]->arg2 = 0;
232               deletePcode(i+1);
233               nchanges++;
234               break;
235
236             case oLTZ   :
237               if (signExtend16(pptr[i]->arg2) < 0)
238                 pptr[i]->arg2 = -1;
239               else
240                 pptr[i]->arg2 = 0;
241               deletePcode(i+1);
242               nchanges++;
243               break;
244
245             case oGTEZ  :
246               if (signExtend16(pptr[i]->arg2) >= 0)
247                 pptr[i]->arg2 = -1;
248               else
249                 pptr[i]->arg2 = 0;
250               deletePcode(i+1);
251               nchanges++;
252               break;
253
254             case oGTZ   :
255               if (pptr[i]->arg2 > 0) pptr[i]->arg2 = -1;
256               else pptr[i]->arg2 = 0;
257               deletePcode(i+1);
258               nchanges++;
259               break;
260
261             case oLTEZ :
262               if (pptr[i]->arg2 <= 0) pptr[i]->arg2 = -1;
263               else pptr[i]->arg2 = 0;
264               deletePcode(i+1);
265               nchanges++;
266               break;
267
268               /*  Simplify comparisons with certain constants */
269
270             case oEQU   :
271               if (pptr[i]->arg2 == 0)
272                 {
273                   pptr[i+1]->op = oEQUZ;
274                   deletePcode(i);
275                   nchanges++;
276                 } /* end if */
277               else if (pptr[i]->arg2 == 1)
278                 {
279                   pptr[i]->op   = oDEC;
280                   pptr[i]->arg2 = 0;
281                   pptr[i+1]->op = oEQUZ;
282                   nchanges++;
283                 } /* end else if */
284               else if (signExtend16(pptr[i]->arg2) == -1)
285                 {
286                   pptr[i]->op   = oINC;
287                   pptr[i]->arg2 = 0;
288                   pptr[i+1]->op = oEQUZ;
289                   nchanges++;
290                 } /* end else if */
291               else i++;
292               break;
293
294             case oNEQ   :
295               if (pptr[i]->arg2 == 0)
296                 {
297                   pptr[i+1]->op = oNEQZ;
298                   deletePcode(i);
299                   nchanges++;
300                 } /* end if */
301               else if (pptr[i]->arg2 == 1)
302                 {
303                   pptr[i]->op   = oDEC;
304                   pptr[i]->arg2 = 0;
305                   pptr[i+1]->op = oNEQZ;
306                   nchanges++;
307                 } /* end else if */
308               else if (signExtend16(pptr[i]->arg2) == -1)
309                 {
310                   pptr[i]->op   = oINC;
311                   pptr[i]->arg2 = 0;
312                   pptr[i+1]->op = oNEQZ;
313                   nchanges++;
314                 } /* end else if */
315               else i++;
316               break;
317
318             case oLT    :
319               if (pptr[i]->arg2 == 0)
320                 {
321                   pptr[i+1]->op = oLTZ;
322                   deletePcode(i);
323                   nchanges++;
324                 } /* end if */
325               else if (pptr[i]->arg2 == 1)
326                 {
327                   pptr[i]->op   = oDEC;
328                   pptr[i]->arg2 = 0;
329                   pptr[i+1]->op = oLTZ;
330                   nchanges++;
331                 } /* end else if */
332               else if (signExtend16(pptr[i]->arg2) == -1)
333                 {
334                   pptr[i]->op   = oINC;
335                   pptr[i]->arg2 = 0;
336                   pptr[i+1]->op = oLTZ;
337                   nchanges++;
338                 } /* end else if */
339               else i++;
340               break;
341
342             case oGTE   :
343               if (pptr[i]->arg2 == 0)
344                 {
345                   pptr[i+1]->op = oGTEZ;
346                   deletePcode(i);
347                   nchanges++;
348                 } /* end if */
349               else if (pptr[i]->arg2 == 1)
350                 {
351                   pptr[i]->op   = oDEC;
352                   pptr[i]->arg2 = 0;
353                   pptr[i+1]->op = oGTEZ;
354                   nchanges++;
355                 } /* end else if */
356               else if (signExtend16(pptr[i]->arg2) == -1)
357                 {
358                   pptr[i]->op   = oINC;
359                   pptr[i]->arg2 = 0;
360                   pptr[i+1]->op = oGTEZ;
361                   nchanges++;
362                 } /* end else if */
363               else i++;
364               break;
365
366             case oGT    :
367               if (pptr[i]->arg2 == 0)
368                 {
369                   pptr[i+1]->op = oGTZ;
370                   deletePcode(i);
371                   nchanges++;
372                 } /* end if */
373               else if (pptr[i]->arg2 == 1)
374                 {
375                   pptr[i]->op   = oDEC;
376                   pptr[i]->arg2 = 0;
377                   pptr[i+1]->op = oGTZ;
378                   nchanges++;
379                 } /* end else if */
380               else if (signExtend16(pptr[i]->arg2) == -1)
381                 {
382                   pptr[i]->op   = oINC;
383                   pptr[i]->arg2 = 0;
384                   pptr[i+1]->op = oGTZ;
385                   nchanges++;
386                 } /* end else if */
387               else i++;
388               break;
389
390             case oLTE   :
391               if (pptr[i]->arg2 == 0)
392                 {
393                   pptr[i+1]->op = oLTEZ;
394                   deletePcode(i);
395                   nchanges++;
396                 } /* end if */
397               else if (pptr[i]->arg2 == 1)
398                 {
399                   pptr[i]->op   = oDEC;
400                   pptr[i]->arg2 = 0;
401                   pptr[i+1]->op = oLTEZ;
402                   nchanges++;
403                 } /* end else if */
404               else if (signExtend16(pptr[i]->arg2) == -1)
405                 {
406                   pptr[i]->op   = oINC;
407                   pptr[i]->arg2 = 0;
408                   pptr[i+1]->op = oLTEZ;
409                   nchanges++;
410                 } /* end else if */
411               else i++;
412               break;
413
414         /* Simplify or delete condition branches on constants */
415
416             case oJEQUZ :
417               if (pptr[i]->arg2 == 0)
418                 {
419                   pptr[i+1]->op = oJMP;
420                   deletePcode(i);
421                 } /* end if */
422               else 
423                 deletePcodePair(i, (i+1));
424               nchanges++;
425               break;
426
427             case oJNEQZ :
428               if (pptr[i]->arg2 != 0)
429                 {
430                   pptr[i+1]->op = oJMP;
431                   deletePcode(i);
432                 } /* end if */
433               else 
434                 deletePcodePair(i, (i+1));
435               nchanges++;
436               break;
437
438             case oJLTZ  :
439               if (signExtend16(pptr[i]->arg2) < 0)
440                 {
441                   pptr[i+1]->op = oJMP;
442                   deletePcode(i);
443                 } /* end if */
444               else 
445                 deletePcodePair(i, (i+1));
446               nchanges++;
447               break;
448
449             case oJGTEZ :
450               if (signExtend16(pptr[i]->arg2) >= 0)
451                 {
452                   pptr[i+1]->op = oJMP;
453                   deletePcode(i);
454                 } /* end if */
455               else 
456                 deletePcodePair(i, (i+1));
457               nchanges++;
458               break;
459
460             case oJGTZ  :
461               if (pptr[i]->arg2 > 0)
462                 {
463                   pptr[i+1]->op = oJMP;
464                   deletePcode(i);
465                 } /* end if */
466               else 
467                 deletePcodePair(i, (i+1));
468               nchanges++;
469               break;
470
471             case oJLTEZ :
472               if (pptr[i]->arg2 <= 0)
473                 {
474                   pptr[i+1]->op = oJMP;
475                   deletePcode(i);
476                 } /* end if */
477               else 
478                 deletePcodePair(i, (i+1));
479               nchanges++;
480               break;
481
482             default     :
483               i++;
484               break;
485             } /* end switch */
486
487           /* If the oPUSH instruction is still there, see if we can now */
488           /* represent it with an oPUSHB instruction */
489
490           if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
491             {
492               pptr[i]->op   = oPUSHB;
493               pptr[i]->arg1 = pptr[i]->arg2;
494               pptr[i]->arg2 = 0;
495             } /* end if */
496         } /* end if */
497
498       /* Delete multiple modifications of DSEG pointer */
499
500       else if (pptr[i]->op == oINDS)
501         {
502           if (pptr[i+1]->op == oINDS)
503             {
504               pptr[i]->arg2 += pptr[i+1]->arg2;
505               deletePcode(i+1);
506             } /* end if */
507           else i++;
508         } /* end else if */
509       else i++;
510     } /* end while */
511
512   return (nchanges);
513
514} /* end unaryOptimize */
515
516/**********************************************************************/
517
518int16_t binaryOptimize(void)
519{
520  int16_t nchanges = 0;
521  register int16_t stmp16;
522  register int16_t i;
523
524  TRACE(stderr, "[binaryOptimize]");
525
526  /* At least two pcodes are needed to perform the following binary */
527  /* operator optimizations */
528
529  i = 0;
530  while (i < nops-2)
531    {
532      if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB))
533        {
534          if ((pptr[i+1]->op == oPUSH) || (pptr[i+1]->op == oPUSHB))
535            {
536              /* Turn the oPUSHBs into an oPUSHs op (temporarily) */
537
538              if (pptr[i]->op == oPUSHB)
539                {
540                  pptr[i]->op   = oPUSH;
541                  pptr[i]->arg2 = pptr[i]->arg1;
542                  pptr[i]->arg1 = 0;
543                } /* end if */
544
545              if (pptr[i+1]->op == oPUSHB)
546                {
547                  pptr[i+1]->op   = oPUSH;
548                  pptr[i+1]->arg2 = pptr[i+1]->arg1;
549                  pptr[i+1]->arg1 = 0;
550                } /* end if */
551
552              switch (pptr[i+2]->op)
553                {
554                case oADD :
555                  pptr[i]->arg2 += pptr[i+1]->arg2;
556                  deletePcodePair((i+1), (i+2));
557                  nchanges++;
558                  break;
559
560                case oSUB :
561                  pptr[i]->arg2 -= pptr[i+1]->arg2;
562                  deletePcodePair((i+1), (i+2));
563                  nchanges++;
564                  break;
565
566                case oMUL :
567                  pptr[i]->arg2 *= pptr[i+1]->arg2;
568                  deletePcodePair((i+1), (i+2));
569                  nchanges++;
570                  break;
571
572                case oDIV :
573                  stmp16 = pptr[i]->arg2 / signExtend16(pptr[i+1]->arg2);
574                  pptr[i]->arg2 = stmp16;
575                  deletePcodePair((i+1), (i+2));
576                  nchanges++;
577                  break;
578
579                case oMOD :
580                  pptr[i]->arg2 %= pptr[i+1]->arg2;
581                  deletePcodePair((i+1), (i+2));
582                  nchanges++;
583                  break;
584
585                case oSLL :
586                  pptr[i]->arg2 <<= pptr[i+1]->arg2;
587                  deletePcodePair((i+1), (i+2));
588                  nchanges++;
589                  break;
590
591                case oSRL :
592                  pptr[i]->arg2 >>= pptr[i+1]->arg2;
593                  deletePcodePair((i+1), (i+2));
594                  nchanges++;
595                  break;
596
597                case oSRA :
598                  stmp16 = (((int16_t)pptr[i]->arg2) >> pptr[i+1]->arg2);
599                  pptr[i]->arg2 = (uint16_t)stmp16;
600                  deletePcodePair((i+1), (i+2));
601                  nchanges++;
602                  break;
603
604                case oOR  :
605                  pptr[i]->arg2 |= pptr[i+1]->arg2;
606                  deletePcodePair((i+1), (i+2));
607                  nchanges++;
608                  break;
609
610                case oAND :
611                  pptr[i]->arg2 &= pptr[i+1]->arg2;
612                  deletePcodePair((i+1), (i+2));
613                  nchanges++;
614                  break;
615
616                case oEQU :
617                  if (pptr[i]->arg2 == pptr[i+1]->arg2) pptr[i]->arg2 = -1;
618                  else pptr[i]->arg2 = 0;
619                  deletePcodePair((i+1), (i+2));
620                  nchanges++;
621                  break;
622
623                case oNEQ :
624                  if ((int16_t)pptr[i]->arg2 != (int16_t)pptr[i+1]->arg2)
625                    pptr[i]->arg2 = -1;
626                  else
627                    pptr[i]->arg2 = 0;
628                  deletePcodePair((i+1), (i+2));
629                  nchanges++;
630                  break;
631
632                case oLT  :
633                  if ((int16_t)pptr[i]->arg2 < (int16_t)pptr[i+1]->arg2)
634                    pptr[i]->arg2 = -1;
635                  else
636                    pptr[i]->arg2 = 0;
637                  deletePcodePair((i+1), (i+2));
638                  nchanges++;
639                  break;
640
641                case oGTE :
642                  if ((int16_t)pptr[i]->arg2 >= (int16_t)pptr[i+1]->arg2)
643                    pptr[i]->arg2 = -1;
644                  else
645                    pptr[i]->arg2 = 0;
646                  deletePcodePair((i+1), (i+2));
647                  nchanges++;
648                  break;
649
650                case oGT  :
651                  if ((int16_t)pptr[i]->arg2 > (int16_t)pptr[i+1]->arg2)
652                    pptr[i]->arg2 = -1;
653                  else
654                    pptr[i]->arg2 = 0;
655                  deletePcodePair((i+1), (i+2));
656                  nchanges++;
657                  break;
658
659                case oLTE :
660                  if ((int16_t)pptr[i]->arg2 <= (int16_t)pptr[i+1]->arg2)
661                    pptr[i]->arg2 = -1;
662                  else
663                    pptr[i]->arg2 = 0;
664                  deletePcodePair((i+1), (i+2));
665                  nchanges++;
666                  break;
667
668                default   :
669                  i++;
670                  break;
671                } /* end switch */
672
673              /* If the oPUSH instruction is still there, see if we can now */
674              /* represent it with an oPUSHB instruction */
675
676              if (pptr[i] && (pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
677                {
678                  pptr[i]->op   = oPUSHB;
679                  pptr[i]->arg1 = pptr[i]->arg2;
680                  pptr[i]->arg2 = 0;
681                } /* end if */
682
683              if (pptr[i+1] && (pptr[i+1]->op == oPUSH) && (pptr[i+1]->arg2 < 256))
684                {
685                  pptr[i+1]->op   = oPUSHB;
686                  pptr[i+1]->arg1 = pptr[i+1]->arg2;
687                  pptr[i+1]->arg2 = 0;
688                } /* end if */
689            } /* end if */
690
691          /* A single (constant) pcode is sufficient to perform the */
692          /* following binary operator optimizations */
693
694          else if ((pptr[i+1]->op == oLDSH) || (pptr[i+1]->op == oLDSB) ||
695                   (pptr[i+1]->op == oLAS)  || (pptr[i+1]->op == oLAC))
696            {
697              /* Turn the oPUSHB into a oPUSH op (temporarily) */
698
699              if (pptr[i]->op == oPUSHB)
700                {
701                  pptr[i]->op   = oPUSH;
702                  pptr[i]->arg2 = pptr[i]->arg1;
703                  pptr[i]->arg1 = 0;
704                } /* end if */
705
706              switch (pptr[i+2]->op)
707                {
708                case oADD :
709                  if (pptr[i]->arg2 == 0)
710                    {
711                      deletePcodePair(i, (i+2));
712                      nchanges++;
713                    } /* end if */
714                  else if (pptr[i]->arg2 == 1)
715                    {
716                      pptr[i+2]->op = oINC;
717                      deletePcode(i);
718                      nchanges++;
719                    } /* end else if */
720                  else if (pptr[i]->arg2 == (uint16_t)-1)
721                    {
722                      pptr[i+2]->op = oDEC;
723                      deletePcode(i);
724                      nchanges++;
725                    } /* end else if */
726                  else i++;
727                  break;
728
729                case oSUB :
730                  if (pptr[i]->arg2 == 0)
731                    {
732                      pptr[i]->op = oNEG;
733                      deletePcode(i);
734                      nchanges++;
735                    } /* end if */
736                  else i++;
737                  break;
738
739                case oMUL :
740                  stmp16 = 0;
741                  switch (pptr[i]->arg2)
742                    {
743                    case 1 :
744                      deletePcodePair(i, (i+2));
745                      nchanges++;
746                      break;
747                    case 16384 : stmp16++;
748                    case  8192 : stmp16++;
749                    case  4096 : stmp16++;
750                    case  2048 : stmp16++;
751                    case  1024 : stmp16++;
752                    case   512 : stmp16++;
753                    case   256 : stmp16++;
754                    case   128 : stmp16++;
755                    case    64 : stmp16++;
756                    case    32 : stmp16++;
757                    case    16 : stmp16++;
758                    case     8 : stmp16++;
759                    case     4 : stmp16++;
760                    case     2 : stmp16++;
761                      pptr[i]->op     = pptr[i+1]->op;
762                      pptr[i]->arg1   = pptr[i+1]->arg1;
763                      pptr[i]->arg2   = pptr[i+1]->arg2;
764                      pptr[i+1]->op   = oPUSH;
765                      pptr[i+1]->arg1 = 0;
766                      pptr[i+1]->arg2 = stmp16;
767                      pptr[i+2]->op   = oSLL;
768                      nchanges++;
769                      i++;
770                      break;
771
772                    default :
773                      i++;
774                      break;
775                    } /* end switch */
776                  break;
777
778                case oOR  :
779                  if (pptr[i]->arg2 == 0)
780                    {
781                      deletePcodePair(i, (i+2));
782                      nchanges++;
783                    } /* end if */
784                  else i++;
785                  break;
786
787                case oAND :
788                  if (pptr[i]->arg2 == 0xffff)
789                    {
790                      deletePcodePair(i, (i+2));
791                      nchanges++;
792                    } /* end if */
793                  else i++;
794                  break;
795
796                case oEQU :
797                  if (pptr[i]->arg2 == 0)
798                    {
799                      pptr[i+2]->op = oEQUZ;
800                      deletePcode(i);
801                      nchanges++;
802                    } /* end if */
803                  else i++;
804                  break;
805
806                case oNEQ :
807                  if (pptr[i]->arg2 == 0)
808                    {
809                      pptr[i+2]->op = oNEQZ;
810                      deletePcode(i);
811                      nchanges++;
812                    } /* end if */
813                  else i++;
814                  break;
815
816                case oLT  :
817                  if (pptr[i]->arg2 == 0)
818                    {
819                      pptr[i+2]->op = oGTEZ;
820                      deletePcode(i);
821                      nchanges++;
822                    } /* end if */
823                  else i++;
824                  break;
825
826                case oGTE :
827                  if (pptr[i]->arg2 == 0)
828                    {
829                      pptr[i+2]->op = oLTZ;
830                      deletePcode(i);
831                      nchanges++;
832                    } /* end if */
833                  else i++;
834                  break;
835
836                case oGT  :
837                  if (pptr[i]->arg2 == 0)
838                    {
839                      pptr[i+2]->op = oLTEZ;
840                      deletePcode(i);
841                      nchanges++;
842                    } /* end if */
843                  else i++;
844                  break;
845
846                case oLTE :
847                  if (pptr[i]->arg2 == 0)
848                    {
849                      pptr[i+2]->op = oGTZ;
850                      deletePcode(i);
851                      nchanges++;
852                    } /* end if */
853                  else i++;
854                  break;
855
856                default   :
857                  i++;
858                  break;
859
860                } /* end switch */
861
862              /* If the oPUSH instruction is still there, see if we can now */
863              /* represent it with an oPUSHB instruction */
864
865              if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
866                {
867                  pptr[i]->op   = oPUSHB;
868                  pptr[i]->arg1 = pptr[i]->arg2;
869                  pptr[i]->arg2 = 0;
870                } /* end if */
871            } /* end else if */
872          else i++;
873        } /* end if */
874
875      /* Misc improvements on binary operators */
876
877      else if (pptr[i]->op == oNEG)
878        {
879          /* Negation followed by add is subtraction */
880
881          if (pptr[i+1]->op == oADD)
882            {
883               pptr[i+1]->op = oSUB;
884               deletePcode(i);
885               nchanges++;
886            }
887
888          /* Negation followed by subtraction is addition */
889
890          else if (pptr[i]->op == oSUB)
891            {
892               pptr[i+1]->op = oADD;
893               deletePcode(i);
894               nchanges++;
895            }
896          else i++;
897        }
898      else i++;
899    } /* end while */
900
901  return (nchanges);
902
903} /* end binaryOptimize */
904
905/**********************************************************************/
906