diff options
Diffstat (limited to 'misc/pascal/insn32/plopt/polocal.c')
-rw-r--r-- | misc/pascal/insn32/plopt/polocal.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/misc/pascal/insn32/plopt/polocal.c b/misc/pascal/insn32/plopt/polocal.c new file mode 100644 index 000000000..551913a49 --- /dev/null +++ b/misc/pascal/insn32/plopt/polocal.c @@ -0,0 +1,271 @@ +/**********************************************************************
+ * polocal.c
+ * P-Code Local Optimizer
+ *
+ * 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 "podefs.h"
+#include "pinsn32.h"
+
+#include "pofflib.h"
+#include "paslib.h"
+#include "pinsn.h"
+#include "pcopt.h"
+#include "plopt.h"
+#include "pjopt.h"
+#include "polocal.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void initPTable (void);
+static void putPCodeFromTable (void);
+static void setupPointer (void);
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+OPTYPE ptable [WINDOW]; /* Pcode Table */
+OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */
+
+int nops = 0; /* No. Valid Pcode Pointers */
+int end_out = 0; /* 1 = oEND pcode has been output */
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static poffHandle_t myPoffHandle; /* Handle to POFF object */
+static poffProgHandle_t myPoffProgHandle;/* Handle to temporary POFF object */
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+void localOptimization(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle)
+{
+ int nchanges;
+
+ TRACE(stderr, "[pass2]");
+
+ /* Save the handles for use by other, private functions */
+
+ myPoffHandle = poffHandle;
+ myPoffProgHandle = poffProgHandle;
+
+ /* Initialization */
+
+ initPTable();
+
+ /* Outer loop traverse the file op-code by op-code until the oEND P-Code
+ * has been output. NOTE: it is assumed throughout that oEND is the
+ * final P-Code in the program data section.
+ */
+
+ while (!(end_out))
+ {
+ /* The inner loop optimizes the buffered P-Codes until no further
+ * changes can be made. Then the outer loop will advance the buffer
+ * by one P-Code
+ */
+
+ do
+ {
+ nchanges = unaryOptimize ();
+ nchanges += binaryOptimize();
+ nchanges += BranchOptimize();
+ nchanges += LoadOptimize();
+ nchanges += StoreOptimize();
+ } while (nchanges);
+
+ putPCodeFromTable();
+ }
+}
+
+/***********************************************************************/
+
+void deletePcode(int delIndex)
+{
+ TRACE(stderr, "[deletePcode]");
+
+ PUTOP(pptr[delIndex], oNOP);
+ PUTARG(pptr[delIndex], 0);
+ setupPointer();
+}
+
+/**********************************************************************/
+
+void deletePcodePair(int delIndex1, int delIndex2)
+{
+ TRACE(stderr, "[deletePcodePair]");
+
+ PUTOP(pptr[delIndex1], oNOP);
+ PUTARG(pptr[delIndex1], 0);
+ PUTOP(pptr[delIndex2], oNOP);
+ PUTARG(pptr[delIndex2], 0);
+ setupPointer();
+}
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void putPCodeFromTable(void)
+{
+ register int i;
+
+ TRACE(stderr, "[putPCodeFromTable]");
+
+ /* Transfer all buffered P-Codes (except NOPs) to the optimized file */
+ do
+ {
+ if ((GETOP(&ptable[0]) != oNOP) && !(end_out))
+ {
+ insn_AddTmpOpCode(myPoffProgHandle, &ptable[0]);
+ end_out = (GETOP(&ptable[0]) == oEND);
+ }
+
+ /* Move all P-Codes down one slot */
+
+ for (i = 1; i < WINDOW; i++)
+ {
+ ptable[i-1] = ptable[i];
+ }
+
+ /* Then fill the end slot with a new P-Code from the input file */
+
+ insn_GetOpCode(myPoffHandle, &ptable[WINDOW-1]);
+
+ } while (GETOP(&ptable[0]) == oNOP);
+ setupPointer();
+}
+
+/**********************************************************************/
+
+static void setupPointer(void)
+{
+ register int pindex;
+
+ TRACE(stderr, "[setupPointer]");
+
+ for (pindex = 0; pindex < WINDOW; pindex++)
+ pptr[pindex] = (OPTYPE *) NULL;
+
+ nops = 0;
+ for (pindex = 0; pindex < WINDOW; pindex++)
+ {
+ switch (GETOP(&ptable[pindex]))
+ {
+ /* Terminate list when a break from sequential logic is
+ * encountered
+ */
+
+ case oRET :
+ case oEND :
+ case oJMP :
+ case oLABEL :
+ case oPCAL :
+ return;
+
+ /* Terminate list when a condition break from sequential logic is
+ * encountered but include the conditional branch in the list
+ */
+
+ case oJEQUZ :
+ case oJNEQZ :
+ case oJLTZ :
+ case oJGTEZ :
+ case oJGTZ :
+ case oJLTEZ :
+ pptr[nops] = &ptable[pindex];
+ nops++;
+ return;
+
+ /* Skip over NOPs and comment class pcodes */
+
+ case oNOP :
+ case oLINE :
+ break;
+
+ /* Include all other pcodes in the optimization list and continue */
+
+ default :
+ pptr[nops] = &ptable[pindex];
+ nops++;
+ }
+ }
+}
+
+/**********************************************************************/
+
+static void initPTable(void)
+{
+ register int i;
+
+ TRACE(stderr, "[intPTable]");
+
+ /* Skip over leading pcodes. NOTE: assumes executable begins after
+ * the first oLABEL pcode
+ */
+
+ do
+ {
+ insn_GetOpCode(myPoffHandle, &ptable[0]);
+ insn_AddTmpOpCode(myPoffProgHandle, &ptable[0]);
+ }
+ while ((GETOP(&ptable[0]) != oLABEL) && (GETOP(&ptable[0]) != oEND));
+
+ /* Fill the pcode window and setup pointers to working section */
+
+ for (i = 0; i < WINDOW; i++)
+ {
+ insn_GetOpCode(myPoffHandle, &ptable[i]);
+ }
+ setupPointer();
+}
+
+/***********************************************************************/
|