diff options
Diffstat (limited to 'misc/pascal/insn32/popt/pcopt.c')
-rw-r--r-- | misc/pascal/insn32/popt/pcopt.c | 1679 |
1 files changed, 840 insertions, 839 deletions
diff --git a/misc/pascal/insn32/popt/pcopt.c b/misc/pascal/insn32/popt/pcopt.c index ee5f4d924..2c4c1fa01 100644 --- a/misc/pascal/insn32/popt/pcopt.c +++ b/misc/pascal/insn32/popt/pcopt.c @@ -1,839 +1,840 @@ -/**********************************************************************
- * pcopt.c
- * Constant Expression Optimizations
- *
- * Copyright (C) 2008 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- **********************************************************************/
-
-/**********************************************************************
- * Included Files
- **********************************************************************/
-
-#include <stdio.h>
-
-#include "keywords.h"
-#include "pdefs.h"
-#include "pinsn32.h"
-
-#include "paslib.h"
-#include "popt.h"
-#include "polocal.h"
-#include "pcopt.h"
-
-/**********************************************************************/
-
-int unaryOptimize(void)
-{
- register uint32 temp;
- register int i;
- int nchanges = 0;
-
- TRACE(stderr, "[unaryOptimize]");
-
- /* At least two pcodes are need to perform unary optimizations */
-
- i = 0;
- while (i < nops-1)
- {
- /* Check for a constant value being pushed onto the stack */
-
- if (GETOP(pptr[i]) == oPUSH)
- {
- switch (GETOP(pptr[i+1]))
- {
- /* Delete unary operators on constants */
- case oNEG :
- PUTARG(pptr[i], -GETARG(pptr[i]));
- deletePcode(i+1);
- nchanges++;
- break;
-
- case oABS :
- if ((sint32)GETARG(pptr[i]) < 0)
- PUTARG(pptr[i], -(sint32)GETARG(pptr[i]));
- deletePcode(i+1);
- nchanges++;
- break;
-
- case oINC :
- PUTARG(pptr[i], GETARG(pptr[i]) + 1);
- deletePcode(i+1);
- nchanges++;
- break;
-
- case oDEC :
- PUTARG(pptr[i], GETARG(pptr[i]) - 1);
- deletePcode(i+1);
- nchanges++;
- break;
-
- case oNOT :
- PUTARG(pptr[i], ~GETARG(pptr[i]));
- PUTARG(pptr[i], ~(GETARG(pptr[i])));
- deletePcode(i+1);
- nchanges++;
- break;
-
- /* Simplify binary operations on constants */
-
- case oADD :
- if (GETARG(pptr[i]) == 0)
- {
- deletePcodePair(i, (i+1));
- nchanges++;
- } /* end if */
- else if (GETARG(pptr[i]) == 1)
- {
- PUTOP(pptr[i+1], oINC);
- deletePcode(i);
- nchanges++;
- } /* end else if */
- else if (GETARG(pptr[i]) == ARGONES)
- {
- PUTOP(pptr[i+1], oDEC);
- deletePcode(i);
- nchanges++;
- } /* end else if */
- else i++;
- break;
-
- case oSUB :
- if (GETARG(pptr[i]) == 0)
- {
- deletePcodePair(i, (i+1));
- nchanges++;
- } /* end if */
- else if (GETARG(pptr[i]) == 1)
- {
- PUTOP(pptr[i+1], oDEC);
- deletePcode(i);
- nchanges++;
- } /* end else if */
- else if (GETARG(pptr[i]) == ARGONES)
- {
- PUTOP(pptr[i+1], oINC);
- deletePcode(i);
- nchanges++;
- } /* end else if */
- else i++;
- break;
-
- case oMUL :
- case oDIV :
- temp = 0;
- switch (GETARG(pptr[i]))
- {
- case 1 :
- deletePcodePair(i, (i+1));
- nchanges++;
- break;
- case 16384 : temp++;
- case 8192 : temp++;
- case 4096 : temp++;
- case 2048 : temp++;
- case 1024 : temp++;
- case 512 : temp++;
- case 256 : temp++;
- case 128 : temp++;
- case 64 : temp++;
- case 32 : temp++;
- case 16 : temp++;
- case 8 : temp++;
- case 4 : temp++;
- case 2 : temp++;
- PUTARG(pptr[i], temp);
- if (GETOP(pptr[i+1]) == oMUL)
- PUTOP(pptr[i+1], oSLL);
- else
- PUTOP(pptr[i+1], oSRA);
- nchanges++;
- i++;
- break;
-
- default :
- i++;
- break;
- } /* end switch */
- break;
-
- case oSLL :
- case oSRL :
- case oSRA :
- case oOR :
- if (GETARG(pptr[i]) == 0)
- {
- deletePcodePair(i, (i+1));
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- case oAND :
- if (GETARG(pptr[i]) == ARGONES)
- {
- deletePcodePair(i, (i+1));
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- /* Delete comparisons of constants to zero */
-
- case oEQUZ :
- if (GETARG(pptr[i]) == 0)
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcode(i+1);
- nchanges++;
- break;
-
- case oNEQZ :
- if (GETARG(pptr[i]) != 0)
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcode(i+1);
- nchanges++;
- break;
-
- case oLTZ :
- if ((sint32)GETARG(pptr[i]) < 0)
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcode(i+1);
- nchanges++;
- break;
-
- case oGTEZ :
- if ((sint32)GETARG(pptr[i]) >= 0)
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcode(i+1);
- nchanges++;
- break;
-
- case oGTZ :
- if (GETARG(pptr[i]) > 0)
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcode(i+1);
- nchanges++;
- break;
-
- case oLTEZ :
- if (GETARG(pptr[i]) <= 0)
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcode(i+1);
- nchanges++;
- break;
-
- /* Simplify comparisons with certain constants */
-
- case oEQU :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+1],oEQUZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else if (GETARG(pptr[i]) == 1)
- {
- PUTOP(pptr[i], oDEC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oEQUZ);
- nchanges++;
- } /* end else if */
- else if ((sint32)GETARG(pptr[i]) == -1)
- {
- PUTOP(pptr[i], oINC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oEQUZ);
- nchanges++;
- } /* end else if */
- else i++;
- break;
-
- case oNEQ :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+1], oNEQZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else if (GETARG(pptr[i]) == 1)
- {
- PUTOP(pptr[i], oDEC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oNEQZ);
- nchanges++;
- } /* end else if */
- else if ((sint32)GETARG(pptr[i]) == -1)
- {
- PUTOP(pptr[i], oINC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oNEQZ);
- nchanges++;
- } /* end else if */
- else i++;
- break;
-
- case oLT :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+1], oLTZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else if (GETARG(pptr[i]) == 1)
- {
- PUTOP(pptr[i], oDEC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oLTZ);
- nchanges++;
- } /* end else if */
- else if ((sint32)GETARG(pptr[i]) == -1)
- {
- PUTOP(pptr[i], oINC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oLTZ);
- nchanges++;
- } /* end else if */
- else i++;
- break;
-
- case oGTE :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+1], oGTEZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else if (GETARG(pptr[i]) == 1)
- {
- PUTOP(pptr[i], oDEC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oGTEZ);
- nchanges++;
- } /* end else if */
- else if ((sint32)GETARG(pptr[i]) == -1)
- {
- PUTOP(pptr[i], oINC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oGTEZ);
- nchanges++;
- } /* end else if */
- else i++;
- break;
-
- case oGT :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+1], oGTZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else if (GETARG(pptr[i]) == 1)
- {
- PUTOP(pptr[i], oDEC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oGTZ);
- nchanges++;
- } /* end else if */
- else if ((sint32)GETARG(pptr[i]) == -1)
- {
- PUTOP(pptr[i], oINC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oGTZ);
- nchanges++;
- } /* end else if */
- else i++;
- break;
-
- case oLTE :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+1], oLTEZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else if (GETARG(pptr[i]) == 1)
- {
- PUTOP(pptr[i], oDEC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oLTEZ);
- nchanges++;
- } /* end else if */
- else if ((sint32)GETARG(pptr[i]) == -1)
- {
- PUTOP(pptr[i], oINC);
- PUTARG(pptr[i], 0);
- PUTOP(pptr[i+1], oLTEZ);
- nchanges++;
- } /* end else if */
- else i++;
- break;
-
- /* Simplify or delete condition branches on constants */
-
- case oJEQUZ :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+1], oJMP);
- deletePcode(i);
- } /* end if */
- else
- deletePcodePair(i, (i+1));
- nchanges++;
- break;
-
- case oJNEQZ :
- if (GETARG(pptr[i]) != 0)
- {
- PUTOP(pptr[i+1], oJMP);
- deletePcode(i);
- } /* end if */
- else
- deletePcodePair(i, (i+1));
- nchanges++;
- break;
-
- case oJLTZ :
- if ((sint32)GETARG(pptr[i]) < 0)
- {
- PUTOP(pptr[i+1], oJMP);
- deletePcode(i);
- } /* end if */
- else
- deletePcodePair(i, (i+1));
- nchanges++;
- break;
-
- case oJGTEZ :
- if ((sint32)GETARG(pptr[i]) >= 0)
- {
- PUTOP(pptr[i+1], oJMP);
- deletePcode(i);
- } /* end if */
- else
- deletePcodePair(i, (i+1));
- nchanges++;
- break;
-
- case oJGTZ :
- if (GETARG(pptr[i]) > 0)
- {
- PUTOP(pptr[i+1], oJMP);
- deletePcode(i);
- } /* end if */
- else
- deletePcodePair(i, (i+1));
- nchanges++;
- break;
-
- case oJLTEZ :
- if (GETARG(pptr[i]) <= 0)
- {
- PUTOP(pptr[i+1], oJMP);
- deletePcode(i);
- } /* end if */
- else
- deletePcodePair(i, (i+1));
- nchanges++;
- break;
-
- default :
- i++;
- break;
- } /* end switch */
- } /* end if */
-
- /* Delete multiple modifications of DSEG pointer */
-
- else if (GETOP(pptr[i]) == oINDS)
- {
- if (GETOP(pptr[i+1]) == oINDS)
- {
- PUTARG(pptr[i], GETARG(pptr[i] + GETARG(pptr[i+1])));
- deletePcode(i+1);
- } /* end if */
- else i++;
- } /* end else if */
- else i++;
- } /* end while */
-
- return (nchanges);
-
-} /* end unaryOptimize */
-
-/**********************************************************************/
-
-int binaryOptimize(void)
-{
- register int i;
- int nchanges = 0;
-
- TRACE(stderr, "[binaryOptimize]");
-
- /* At least two pcodes are needed to perform the following binary */
- /* operator optimizations */
-
- i = 0;
- while (i < nops-2)
- {
- if (GETOP(pptr[i]) == oPUSH)
- {
- if (GETOP(pptr[i+1]) == oPUSH)
- {
- switch (GETOP(pptr[i+2]))
- {
- case oADD :
- PUTARG(pptr[i], GETARG(pptr[i]) + GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oSUB :
- PUTARG(pptr[i], GETARG(pptr[i]) - GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oMUL :
- PUTARG(pptr[i], GETARG(pptr[i]) * GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oDIV :
- PUTARG(pptr[i], GETARG(pptr[i]) / (sint32)GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oMOD :
- PUTARG(pptr[i], GETARG(pptr[i]) % GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oSLL :
- PUTARG(pptr[i], GETARG(pptr[i]) << GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oSRL :
- PUTARG(pptr[i], GETARG(pptr[i]) >> GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oSRA :
- PUTARG(pptr[i], (sint32)GETARG(pptr[i]) >> GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oOR :
- PUTARG(pptr[i], GETARG(pptr[i]) | GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oAND :
- PUTARG(pptr[i], GETARG(pptr[i]) & GETARG(pptr[i+1]));
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oEQU :
- if (GETARG(pptr[i]) == GETARG(pptr[i+1]))
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oNEQ :
- if (GETARG(pptr[i]) != GETARG(pptr[i+1]))
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oLT :
- if ((sint32)GETARG(pptr[i]) < (sint32)GETARG(pptr[i+1]))
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oGTE :
- if ((sint32)GETARG(pptr[i]) >= (sint32)GETARG(pptr[i+1]))
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oGT :
- if ((sint32)GETARG(pptr[i]) > (sint32)GETARG(pptr[i+1]))
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- case oLTE :
- if ((sint32)GETARG(pptr[i]) <= (sint32)GETARG(pptr[i+1]))
- PUTARG(pptr[i], -1);
- else
- PUTARG(pptr[i], 0);
- deletePcodePair((i+1), (i+2));
- nchanges++;
- break;
-
- default :
- i++;
- break;
- } /* end switch */
- } /* end if */
-
- /* A single (constant) pcode is sufficient to perform the */
- /* following binary operator optimizations */
-
- else if ((GETOP(pptr[i+1]) == oLDSH) || (GETOP(pptr[i+1]) == oLDSB) ||
- (GETOP(pptr[i+1]) == oLAS) || (GETOP(pptr[i+1]) == oLAC))
- {
- switch (GETOP(pptr[i+2]))
- {
- case oADD :
- if (GETARG(pptr[i]) == 0)
- {
- deletePcodePair(i, (i+2));
- nchanges++;
- } /* end if */
- else if (GETARG(pptr[i]) == 1)
- {
- PUTOP(pptr[i+2], oINC);
- deletePcode(i);
- nchanges++;
- } /* end else if */
- else if (GETARG(pptr[i]) == ARGONES)
- {
- PUTOP(pptr[i+2], oDEC);
- deletePcode(i);
- nchanges++;
- } /* end else if */
- else i++;
- break;
-
- case oSUB :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i], oNEG);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- case oMUL :
- {
- sint32 stmp32 = 0;
- switch (GETARG(pptr[i]))
- {
- case 1 :
- deletePcodePair(i, (i+2));
- nchanges++;
- break;
- case 16384 : stmp32++;
- case 8192 : stmp32++;
- case 4096 : stmp32++;
- case 2048 : stmp32++;
- case 1024 : stmp32++;
- case 512 : stmp32++;
- case 256 : stmp32++;
- case 128 : stmp32++;
- case 64 : stmp32++;
- case 32 : stmp32++;
- case 16 : stmp32++;
- case 8 : stmp32++;
- case 4 : stmp32++;
- case 2 : stmp32++;
- PUTOP(pptr[i], GETOP(pptr[i+1]));
- PUTARG(pptr[i], GETARG(pptr[i+1]));
- PUTOP(pptr[i+1], oPUSH);
- PUTARG(pptr[i+1], stmp32);
- PUTOP(pptr[i+2], oSLL);
- nchanges++;
- i++;
- break;
-
- default :
- i++;
- break;
- }
- }
- break;
-
- case oOR :
- if (GETARG(pptr[i]) == 0)
- {
- deletePcodePair(i, (i+2));
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- case oAND :
- if (GETARG(pptr[i]) == ARGONES)
- {
- deletePcodePair(i, (i+2));
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- case oEQU :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+2], oEQUZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- case oNEQ :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+2], oNEQZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- case oLT :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+2], oGTEZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- case oGTE :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+2], oLTZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- case oGT :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+2], oLTEZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- case oLTE :
- if (GETARG(pptr[i]) == 0)
- {
- PUTOP(pptr[i+2], oGTZ);
- deletePcode(i);
- nchanges++;
- } /* end if */
- else i++;
- break;
-
- default :
- i++;
- break;
-
- } /* end switch */
- } /* end else if */
- else i++;
- } /* end if */
-
- /* Misc improvements on binary operators */
-
- else if (GETOP(pptr[i]) == oNEG)
- {
- /* Negation followed by add is subtraction */
-
- if (GETOP(pptr[i+1]) == oADD)
- {
- PUTOP(pptr[i+1], oSUB);
- deletePcode(i);
- nchanges++;
- }
-
- /* Negation followed by subtraction is addition */
-
- else if (GETOP(pptr[i]) == oSUB)
- {
- PUTOP(pptr[i+1], oADD);
- deletePcode(i);
- nchanges++;
- }
- else i++;
- }
- else i++;
- } /* end while */
-
- return (nchanges);
-
-} /* end binaryOptimize */
-
-/**********************************************************************/
+/********************************************************************** + * pcopt.c + * Constant Expression Optimizations + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include <stdint.h> +#include <stdio.h> + +#include "keywords.h" +#include "pdefs.h" +#include "pinsn32.h" + +#include "paslib.h" +#include "popt.h" +#include "polocal.h" +#include "pcopt.h" + +/**********************************************************************/ + +int unaryOptimize(void) +{ + register uint32_t temp; + register int i; + int nchanges = 0; + + TRACE(stderr, "[unaryOptimize]"); + + /* At least two pcodes are need to perform unary optimizations */ + + i = 0; + while (i < nops-1) + { + /* Check for a constant value being pushed onto the stack */ + + if (GETOP(pptr[i]) == oPUSH) + { + switch (GETOP(pptr[i+1])) + { + /* Delete unary operators on constants */ + case oNEG : + PUTARG(pptr[i], -GETARG(pptr[i])); + deletePcode(i+1); + nchanges++; + break; + + case oABS : + if ((int32_t)GETARG(pptr[i]) < 0) + PUTARG(pptr[i], -(int32_t)GETARG(pptr[i])); + deletePcode(i+1); + nchanges++; + break; + + case oINC : + PUTARG(pptr[i], GETARG(pptr[i]) + 1); + deletePcode(i+1); + nchanges++; + break; + + case oDEC : + PUTARG(pptr[i], GETARG(pptr[i]) - 1); + deletePcode(i+1); + nchanges++; + break; + + case oNOT : + PUTARG(pptr[i], ~GETARG(pptr[i])); + PUTARG(pptr[i], ~(GETARG(pptr[i]))); + deletePcode(i+1); + nchanges++; + break; + + /* Simplify binary operations on constants */ + + case oADD : + if (GETARG(pptr[i]) == 0) + { + deletePcodePair(i, (i+1)); + nchanges++; + } /* end if */ + else if (GETARG(pptr[i]) == 1) + { + PUTOP(pptr[i+1], oINC); + deletePcode(i); + nchanges++; + } /* end else if */ + else if (GETARG(pptr[i]) == ARGONES) + { + PUTOP(pptr[i+1], oDEC); + deletePcode(i); + nchanges++; + } /* end else if */ + else i++; + break; + + case oSUB : + if (GETARG(pptr[i]) == 0) + { + deletePcodePair(i, (i+1)); + nchanges++; + } /* end if */ + else if (GETARG(pptr[i]) == 1) + { + PUTOP(pptr[i+1], oDEC); + deletePcode(i); + nchanges++; + } /* end else if */ + else if (GETARG(pptr[i]) == ARGONES) + { + PUTOP(pptr[i+1], oINC); + deletePcode(i); + nchanges++; + } /* end else if */ + else i++; + break; + + case oMUL : + case oDIV : + temp = 0; + switch (GETARG(pptr[i])) + { + case 1 : + deletePcodePair(i, (i+1)); + nchanges++; + break; + case 16384 : temp++; + case 8192 : temp++; + case 4096 : temp++; + case 2048 : temp++; + case 1024 : temp++; + case 512 : temp++; + case 256 : temp++; + case 128 : temp++; + case 64 : temp++; + case 32 : temp++; + case 16 : temp++; + case 8 : temp++; + case 4 : temp++; + case 2 : temp++; + PUTARG(pptr[i], temp); + if (GETOP(pptr[i+1]) == oMUL) + PUTOP(pptr[i+1], oSLL); + else + PUTOP(pptr[i+1], oSRA); + nchanges++; + i++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oSLL : + case oSRL : + case oSRA : + case oOR : + if (GETARG(pptr[i]) == 0) + { + deletePcodePair(i, (i+1)); + nchanges++; + } /* end if */ + else i++; + break; + + case oAND : + if (GETARG(pptr[i]) == ARGONES) + { + deletePcodePair(i, (i+1)); + nchanges++; + } /* end if */ + else i++; + break; + + /* Delete comparisons of constants to zero */ + + case oEQUZ : + if (GETARG(pptr[i]) == 0) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcode(i+1); + nchanges++; + break; + + case oNEQZ : + if (GETARG(pptr[i]) != 0) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcode(i+1); + nchanges++; + break; + + case oLTZ : + if ((int32_t)GETARG(pptr[i]) < 0) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcode(i+1); + nchanges++; + break; + + case oGTEZ : + if ((int32_t)GETARG(pptr[i]) >= 0) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcode(i+1); + nchanges++; + break; + + case oGTZ : + if (GETARG(pptr[i]) > 0) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcode(i+1); + nchanges++; + break; + + case oLTEZ : + if (GETARG(pptr[i]) <= 0) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcode(i+1); + nchanges++; + break; + + /* Simplify comparisons with certain constants */ + + case oEQU : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+1],oEQUZ); + deletePcode(i); + nchanges++; + } /* end if */ + else if (GETARG(pptr[i]) == 1) + { + PUTOP(pptr[i], oDEC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oEQUZ); + nchanges++; + } /* end else if */ + else if ((int32_t)GETARG(pptr[i]) == -1) + { + PUTOP(pptr[i], oINC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oEQUZ); + nchanges++; + } /* end else if */ + else i++; + break; + + case oNEQ : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+1], oNEQZ); + deletePcode(i); + nchanges++; + } /* end if */ + else if (GETARG(pptr[i]) == 1) + { + PUTOP(pptr[i], oDEC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oNEQZ); + nchanges++; + } /* end else if */ + else if ((int32_t)GETARG(pptr[i]) == -1) + { + PUTOP(pptr[i], oINC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oNEQZ); + nchanges++; + } /* end else if */ + else i++; + break; + + case oLT : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+1], oLTZ); + deletePcode(i); + nchanges++; + } /* end if */ + else if (GETARG(pptr[i]) == 1) + { + PUTOP(pptr[i], oDEC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oLTZ); + nchanges++; + } /* end else if */ + else if ((int32_t)GETARG(pptr[i]) == -1) + { + PUTOP(pptr[i], oINC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oLTZ); + nchanges++; + } /* end else if */ + else i++; + break; + + case oGTE : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+1], oGTEZ); + deletePcode(i); + nchanges++; + } /* end if */ + else if (GETARG(pptr[i]) == 1) + { + PUTOP(pptr[i], oDEC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oGTEZ); + nchanges++; + } /* end else if */ + else if ((int32_t)GETARG(pptr[i]) == -1) + { + PUTOP(pptr[i], oINC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oGTEZ); + nchanges++; + } /* end else if */ + else i++; + break; + + case oGT : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+1], oGTZ); + deletePcode(i); + nchanges++; + } /* end if */ + else if (GETARG(pptr[i]) == 1) + { + PUTOP(pptr[i], oDEC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oGTZ); + nchanges++; + } /* end else if */ + else if ((int32_t)GETARG(pptr[i]) == -1) + { + PUTOP(pptr[i], oINC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oGTZ); + nchanges++; + } /* end else if */ + else i++; + break; + + case oLTE : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+1], oLTEZ); + deletePcode(i); + nchanges++; + } /* end if */ + else if (GETARG(pptr[i]) == 1) + { + PUTOP(pptr[i], oDEC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oLTEZ); + nchanges++; + } /* end else if */ + else if ((int32_t)GETARG(pptr[i]) == -1) + { + PUTOP(pptr[i], oINC); + PUTARG(pptr[i], 0); + PUTOP(pptr[i+1], oLTEZ); + nchanges++; + } /* end else if */ + else i++; + break; + + /* Simplify or delete condition branches on constants */ + + case oJEQUZ : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+1], oJMP); + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJNEQZ : + if (GETARG(pptr[i]) != 0) + { + PUTOP(pptr[i+1], oJMP); + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJLTZ : + if ((int32_t)GETARG(pptr[i]) < 0) + { + PUTOP(pptr[i+1], oJMP); + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJGTEZ : + if ((int32_t)GETARG(pptr[i]) >= 0) + { + PUTOP(pptr[i+1], oJMP); + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJGTZ : + if (GETARG(pptr[i]) > 0) + { + PUTOP(pptr[i+1], oJMP); + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJLTEZ : + if (GETARG(pptr[i]) <= 0) + { + PUTOP(pptr[i+1], oJMP); + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + } /* end if */ + + /* Delete multiple modifications of DSEG pointer */ + + else if (GETOP(pptr[i]) == oINDS) + { + if (GETOP(pptr[i+1]) == oINDS) + { + PUTARG(pptr[i], GETARG(pptr[i] + GETARG(pptr[i+1]))); + deletePcode(i+1); + } /* end if */ + else i++; + } /* end else if */ + else i++; + } /* end while */ + + return (nchanges); + +} /* end unaryOptimize */ + +/**********************************************************************/ + +int binaryOptimize(void) +{ + register int i; + int nchanges = 0; + + TRACE(stderr, "[binaryOptimize]"); + + /* At least two pcodes are needed to perform the following binary */ + /* operator optimizations */ + + i = 0; + while (i < nops-2) + { + if (GETOP(pptr[i]) == oPUSH) + { + if (GETOP(pptr[i+1]) == oPUSH) + { + switch (GETOP(pptr[i+2])) + { + case oADD : + PUTARG(pptr[i], GETARG(pptr[i]) + GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oSUB : + PUTARG(pptr[i], GETARG(pptr[i]) - GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oMUL : + PUTARG(pptr[i], GETARG(pptr[i]) * GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oDIV : + PUTARG(pptr[i], GETARG(pptr[i]) / (int32_t)GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oMOD : + PUTARG(pptr[i], GETARG(pptr[i]) % GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oSLL : + PUTARG(pptr[i], GETARG(pptr[i]) << GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oSRL : + PUTARG(pptr[i], GETARG(pptr[i]) >> GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oSRA : + PUTARG(pptr[i], (int32_t)GETARG(pptr[i]) >> GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oOR : + PUTARG(pptr[i], GETARG(pptr[i]) | GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oAND : + PUTARG(pptr[i], GETARG(pptr[i]) & GETARG(pptr[i+1])); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oEQU : + if (GETARG(pptr[i]) == GETARG(pptr[i+1])) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oNEQ : + if (GETARG(pptr[i]) != GETARG(pptr[i+1])) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oLT : + if ((int32_t)GETARG(pptr[i]) < (int32_t)GETARG(pptr[i+1])) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oGTE : + if ((int32_t)GETARG(pptr[i]) >= (int32_t)GETARG(pptr[i+1])) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oGT : + if ((int32_t)GETARG(pptr[i]) > (int32_t)GETARG(pptr[i+1])) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oLTE : + if ((int32_t)GETARG(pptr[i]) <= (int32_t)GETARG(pptr[i+1])) + PUTARG(pptr[i], -1); + else + PUTARG(pptr[i], 0); + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + } /* end if */ + + /* A single (constant) pcode is sufficient to perform the */ + /* following binary operator optimizations */ + + else if ((GETOP(pptr[i+1]) == oLDSH) || (GETOP(pptr[i+1]) == oLDSB) || + (GETOP(pptr[i+1]) == oLAS) || (GETOP(pptr[i+1]) == oLAC)) + { + switch (GETOP(pptr[i+2])) + { + case oADD : + if (GETARG(pptr[i]) == 0) + { + deletePcodePair(i, (i+2)); + nchanges++; + } /* end if */ + else if (GETARG(pptr[i]) == 1) + { + PUTOP(pptr[i+2], oINC); + deletePcode(i); + nchanges++; + } /* end else if */ + else if (GETARG(pptr[i]) == ARGONES) + { + PUTOP(pptr[i+2], oDEC); + deletePcode(i); + nchanges++; + } /* end else if */ + else i++; + break; + + case oSUB : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i], oNEG); + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oMUL : + { + int32_t stmp32 = 0; + switch (GETARG(pptr[i])) + { + case 1 : + deletePcodePair(i, (i+2)); + nchanges++; + break; + case 16384 : stmp32++; + case 8192 : stmp32++; + case 4096 : stmp32++; + case 2048 : stmp32++; + case 1024 : stmp32++; + case 512 : stmp32++; + case 256 : stmp32++; + case 128 : stmp32++; + case 64 : stmp32++; + case 32 : stmp32++; + case 16 : stmp32++; + case 8 : stmp32++; + case 4 : stmp32++; + case 2 : stmp32++; + PUTOP(pptr[i], GETOP(pptr[i+1])); + PUTARG(pptr[i], GETARG(pptr[i+1])); + PUTOP(pptr[i+1], oPUSH); + PUTARG(pptr[i+1], stmp32); + PUTOP(pptr[i+2], oSLL); + nchanges++; + i++; + break; + + default : + i++; + break; + } + } + break; + + case oOR : + if (GETARG(pptr[i]) == 0) + { + deletePcodePair(i, (i+2)); + nchanges++; + } /* end if */ + else i++; + break; + + case oAND : + if (GETARG(pptr[i]) == ARGONES) + { + deletePcodePair(i, (i+2)); + nchanges++; + } /* end if */ + else i++; + break; + + case oEQU : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+2], oEQUZ); + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oNEQ : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+2], oNEQZ); + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oLT : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+2], oGTEZ); + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oGTE : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+2], oLTZ); + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oGT : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+2], oLTEZ); + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oLTE : + if (GETARG(pptr[i]) == 0) + { + PUTOP(pptr[i+2], oGTZ); + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + default : + i++; + break; + + } /* end switch */ + } /* end else if */ + else i++; + } /* end if */ + + /* Misc improvements on binary operators */ + + else if (GETOP(pptr[i]) == oNEG) + { + /* Negation followed by add is subtraction */ + + if (GETOP(pptr[i+1]) == oADD) + { + PUTOP(pptr[i+1], oSUB); + deletePcode(i); + nchanges++; + } + + /* Negation followed by subtraction is addition */ + + else if (GETOP(pptr[i]) == oSUB) + { + PUTOP(pptr[i+1], oADD); + deletePcode(i); + nchanges++; + } + else i++; + } + else i++; + } /* end while */ + + return (nchanges); + +} /* end binaryOptimize */ + +/**********************************************************************/ |