summaryrefslogtreecommitdiffstats
path: root/misc/pascal/insn32
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2008-01-05 16:43:27 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2008-01-05 16:43:27 +0000
commit178ecbca116271ce6146a7993fff57237f075665 (patch)
tree80d508fad3dfc488a53f45853d9e1533e974d704 /misc/pascal/insn32
parentac8023b9ec621225f74713ea98873c18a5b1bc33 (diff)
P-code optimizer
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@506 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'misc/pascal/insn32')
-rw-r--r--misc/pascal/insn32/popt/Makefile93
-rw-r--r--misc/pascal/insn32/popt/pcopt.c839
-rw-r--r--misc/pascal/insn32/popt/pcopt.h47
-rw-r--r--misc/pascal/insn32/popt/pfopt.c543
-rw-r--r--misc/pascal/insn32/popt/pfopt.h54
-rw-r--r--misc/pascal/insn32/popt/pjopt.c449
-rw-r--r--misc/pascal/insn32/popt/pjopt.h44
-rw-r--r--misc/pascal/insn32/popt/plopt.c214
-rw-r--r--misc/pascal/insn32/popt/plopt.h43
-rw-r--r--misc/pascal/insn32/popt/polocal.c271
-rw-r--r--misc/pascal/insn32/popt/polocal.h73
-rw-r--r--misc/pascal/insn32/popt/popt.c327
-rw-r--r--misc/pascal/insn32/popt/popt.h52
-rw-r--r--misc/pascal/insn32/popt/psopt.c384
-rw-r--r--misc/pascal/insn32/popt/psopt.h54
15 files changed, 3487 insertions, 0 deletions
diff --git a/misc/pascal/insn32/popt/Makefile b/misc/pascal/insn32/popt/Makefile
new file mode 100644
index 0000000000..5670a6a3d0
--- /dev/null
+++ b/misc/pascal/insn32/popt/Makefile
@@ -0,0 +1,93 @@
+############################################################################
+# insn32/popt/Makefile
+#
+# 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.
+#
+############################################################################
+#
+# Directories
+#
+POPTDIR = ${shell pwd}
+INSNDIR = $(POPTDIR)/..
+PASCAL = $(POPTDIR)/../..
+
+include $(PASCAL)/Make.config
+include $(PASCAL)/Make.defs
+
+INCDIR = $(PASCAL)/include
+LIBDIR = $(PASCAL)/lib
+BINDIR = $(PASCAL)/bin32
+
+# ----------------------------------------------------------------------
+# Tools
+
+EXTRA_INCLUDES = -I$(INSNDIR)/include
+INCLUDES += $(EXTRA_INCLUDES)
+CFLAGS += $(EXTRA_INCLUDES)
+
+# ----------------------------------------------------------------------
+# Objects and targets
+
+POPTSRCS = popt.c psopt.c polocal.c pcopt.c pjopt.c plopt.c pfopt.c
+POPTOBJS = $(POPTSRCS:.c=.o)
+
+OBJS = $(POPTOBJS)
+LIBS = libpoff.a libpas.a
+
+all: popt
+.PHONY: all check_libs popt clean
+
+$(OBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+check_libs:
+ @if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
+ echo "$(LIBDIR)/libpoff.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libpas.a ] ; then \
+ echo "$(LIBDIR)/libpas.a does not exist" ; \
+ exit 1 ; \
+ fi
+ @if [ ! -f $(LIBDIR)/libinsn.a ] ; then \
+ echo "$(LIBDIR)/libinsn.a does not exist" ; \
+ exit 1 ; \
+ fi
+
+$(BINDIR)/popt: check_libs $(POPTOBJS)
+ $(CC) -o $@ $(LDFLAGS) $(POPTOBJS) -lpas -linsn -lpoff
+
+popt: $(BINDIR)/popt
+
+clean:
+ $(RM) popt *.o core *~
+
+# ----------------------------------------------------------------------
diff --git a/misc/pascal/insn32/popt/pcopt.c b/misc/pascal/insn32/popt/pcopt.c
new file mode 100644
index 0000000000..ee5f4d9243
--- /dev/null
+++ b/misc/pascal/insn32/popt/pcopt.c
@@ -0,0 +1,839 @@
+/**********************************************************************
+ * 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 */
+
+/**********************************************************************/
diff --git a/misc/pascal/insn32/popt/pcopt.h b/misc/pascal/insn32/popt/pcopt.h
new file mode 100644
index 0000000000..f638fcf281
--- /dev/null
+++ b/misc/pascal/insn32/popt/pcopt.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * pcopt.h
+ * External Declarations associated with PCOPT.C
+ *
+ * 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.
+ *
+ ***************************************************************************/
+
+#ifndef __PCOPT_H
+#define __PCOPT_H
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern int unaryOptimize ( void );
+extern int binaryOptimize ( void );
+
+#endif /* __PCOPT_H */
diff --git a/misc/pascal/insn32/popt/pfopt.c b/misc/pascal/insn32/popt/pfopt.c
new file mode 100644
index 0000000000..de07400bf2
--- /dev/null
+++ b/misc/pascal/insn32/popt/pfopt.c
@@ -0,0 +1,543 @@
+/**********************************************************************
+ * pfopt.c
+ * Finalization of optimized image
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "podefs.h"
+#include "pedefs.h"
+#include "pinsn32.h"
+#include "poff.h"
+
+#include "paslib.h"
+#include "pofflib.h"
+#include "popt.h"
+#include "pfopt.h"
+#include "pinsn.h"
+#include "perr.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Types
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Inline Functions
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/**********************************************************************/
+
+static void pass1(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ OPTYPE op;
+ uint32 pc;
+ int opsize;
+ int fileno = 0;
+
+ /* Build label / line number reference table
+ *
+ * CASE 1: LABEL
+ * Add label number + PC to table
+ * discard
+ * CASE 2: LINE
+ * genereate a line number reference
+ * discard
+ * ELSE:
+ * pass through with no additional action
+ */
+
+ pc = 0;
+ do
+ {
+ opsize = insn_GetOpCode(poffHandle, &op);
+ if (GETOP(&op) == oLABEL)
+ {
+ poffAddToDefinedLabelTable(GETARG(&op), pc);
+ }
+ else if (GETOP(&op) == oINCLUDE)
+ {
+ fileno = GETARG(&op);
+ }
+ else if (GETOP(&op) == oLINE)
+ {
+ poffAddLineNumber(poffHandle, GETARG(&op), fileno, pc);
+ }
+ else
+ {
+ insn_AddTmpOpCode(poffProgHandle, &op);
+ pc += opsize;
+ }
+ }
+ while (GETOP(&op) != oEND);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+}
+
+/**********************************************************************/
+
+static void pass2(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ poffSymHandle_t poffSymHandle;
+ sint32 symIndex;
+ sint32 nchanges = 0;
+
+ /* Get a container to temporarily hold any modifications that we
+ * make to the symbol table.
+ */
+
+ poffSymHandle = poffCreateSymHandle();
+ if (poffSymHandle == NULL)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ /* Now read all of the symbols. (1) Add each undefined code reference
+ * to the label reference table, and (2) Change each defined code
+ * reference from a label to a program data section offset.
+ */
+
+ do
+ {
+ poffLibSymbol_t symbol;
+ symIndex = poffGetSymbol(poffHandle, &symbol);
+ if (symIndex >= 0)
+ {
+ if ((symbol.type == STT_PROC) || (symbol.type == STT_FUNC))
+ {
+ /* It is a symbol associated with the program data section.
+ * Has is value been defined?
+ */
+
+ if ((symbol.flags & STF_UNDEFINED) != 0)
+ {
+ /* No... Add it to the list of undefined labels */
+
+ poffAddToUndefinedLabelTable(symbol.value, symIndex);
+ }
+ else
+ {
+ /* It is a defined symbol. In this case, we should have
+ * encountered its LABEL marker in the pass1 processing
+ * and the following look up should not fail.
+ */
+ sint32 value = poffGetPcForDefinedLabel(symbol.value);
+ if (value < 0)
+ {
+ DEBUG(stdout, "Failed to find label L%04lx\n", symbol.value);
+ fatal(ePOFFCONFUSION);
+ }
+ else
+ {
+ /* Replace the lavel value with the section offset
+ * (pc) value.
+ */
+
+ symbol.value = value;
+ nchanges++;
+ }
+ }
+ }
+
+ /* In either event, we will want to save the symbol in case
+ * we need to re-write the symbol table.
+ */
+
+ (void)poffAddTmpSymbol(poffHandle, poffSymHandle, &symbol);
+ }
+ }
+ while (symIndex >= 0);
+
+ /* We any changes made to the symbol table in the temporary container? */
+
+ if (nchanges != 0)
+ {
+ /* Yes, update the symbol table */
+
+ poffReplaceSymbolTable(poffHandle, poffSymHandle);
+
+ }
+
+ /* Release the symbol container. */
+
+ poffDestroySymHandle(poffSymHandle);
+}
+
+/**********************************************************************/
+
+static void pass3(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ OPTYPE op;
+ uint32 pc;
+ uint32 opsize;
+
+ /* Read each opcode, generate relocation information and
+ * replace label references with program section offsets.
+ *
+ * CASE 1: LAC
+ * generate RODATA relocation entry
+ * CASE 2: PCAL instructions
+ * replace label with I-space offset, OR
+ * generate a PROGRAM relocation entry
+ * CASE 3: J* instructions
+ * replace label with I-space offset
+ * CASE 4: LDS*, STS*, and LAS* instructions
+ * generate a STACK relocation (if imported?)
+ * ELSE:
+ * pass through with no additional action
+ */
+
+ pc = 0;
+ do
+ {
+ opsize = insn_GetOpCode(poffHandle, &op);
+ switch (GETOP(&op))
+ {
+ /* Load of an address in the rodata section */
+
+ case oLAC:
+ /* We are referencing something from the rodata section.
+ * No special action need be taken.
+ */
+ break;
+
+ /* Call to a procedure or function. */
+
+ case oPCAL:
+ {
+ /* Check if this is a defined label, i.e., a call to
+ * procedure or function in the same file.
+ */
+
+ sint32 value = poffGetPcForDefinedLabel(GETARG(&op));
+ if (value >= 0)
+ {
+ /* Yes... replace the label reference with
+ * a text section offset. No relocation record
+ * is needed in this case. The only relocation
+ * may be performed is a subsequent program data
+ * section offset.
+ */
+
+ PUTARG(&op, value);
+ }
+ else
+ {
+ /* Check if this is a undefined label. This would
+ * occur for a call to a procedure or a function that
+ * is defined in some other unit file.
+ */
+
+ value = poffGetSymIndexForUndefinedLabel(GETARG(&op));
+ if (value >= 0)
+ {
+ /* Use the value zero now */
+
+ PUTARG(&op, 0);
+
+ /* And generate a symbol-based relocation */
+
+ (void)poffAddRelocation(poffHandle, RLT_PCAL, value, pc);
+ }
+ else
+ {
+ DEBUG(stdout, "Failed to find call label L%04x\n",
+ GETARG(&op));
+ fatal(ePOFFCONFUSION);
+ }
+ }
+ }
+ break;
+
+ /* Jumps to "nearby" addresses */
+
+ case oJMP: /* Unconditional */
+ case oJEQUZ: /* Unary comparisons with zero */
+ case oJNEQZ:
+ case oJLTZ:
+ case oJGTEZ:
+ case oJGTZ:
+ case oJLTEZ:
+ case oJEQU: /* Binary comparisons */
+ case oJNEQ:
+ case oJLT:
+ case oJGTE:
+ case oJGT:
+ case oJLTE:
+ {
+ /* Check if this is a defined label. This must be the case
+ * because there can be no jumps into a unit file.
+ */
+
+ sint32 value = poffGetPcForDefinedLabel(GETARG(&op));
+ if (value >= 0)
+ {
+ /* Yes... replace the label reference with
+ * a text section offset. No relocation record
+ * is needed in this case. The only relocation
+ * may be performed is a subsequent program data
+ * sectioin offset.
+ */
+
+ PUTARG(&op, value);
+ }
+ else
+ {
+ DEBUG(stdout, "Failed to find jump label L%04x\n",
+ GETARG(&op));
+ fatal(ePOFFCONFUSION);
+ }
+ }
+ break;
+
+ /* References to stack via level offset */
+
+ case oLAS: /* Load stack address */
+ case oLASX:
+ case oLDS: /* Load value */
+ case oLDSH:
+ case oLDSB:
+ case oLDSM:
+ case oSTS: /* Store value */
+ case oSTSH:
+ case oSTSB:
+ case oSTSM:
+ case oLDSX:
+ case oLDSXH: /* Load value indexed */
+ case oLDSXB:
+ case oLDSXM:
+ case oSTSX: /* Store value indexed */
+ case oSTSXH:
+ case oSTSXB:
+ case oSTSXM:
+ {
+#warning REVISIT
+ }
+ break;
+
+ /* Otherwise, it is not an interesting opcode */
+ default:
+ break;
+ }
+
+ /* Save the potentially modified opcode in the temporary
+ * program data container.
+ */
+
+ insn_AddTmpOpCode(poffProgHandle, &op);
+ pc += opsize;
+ }
+ while (GETOP(&op) != oEND);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+}
+
+/**********************************************************************/
+/* Fixed label references in the debug function information */
+
+static void pass4(poffHandle_t poffHandle)
+{
+ poffLibDebugFuncInfo_t *pDebugInfoHead = NULL;
+ poffLibDebugFuncInfo_t *pDebugInfoTail = NULL;
+ poffLibDebugFuncInfo_t *pDebugInfo;
+ poffLibDebugFuncInfo_t *pNextDebugInfo;
+
+ /* Read all function debug information into a link list */
+
+ while ((pDebugInfo = poffGetDebugFuncInfo(poffHandle)) != NULL)
+ {
+ if (!pDebugInfoHead)
+ {
+ pDebugInfoHead = pDebugInfo;
+ }
+ else
+ {
+ pDebugInfoTail->next = pDebugInfo;
+ }
+ pDebugInfoTail = pDebugInfo;
+ }
+
+ /* Convert all of the label references to pcode offsets */
+
+ for (pDebugInfo = pDebugInfoHead; pDebugInfo; pDebugInfo = pDebugInfo->next)
+ {
+ /* Check if this is a defined label. This must be the case
+ * because there can be no jumps into a unit file.
+ */
+
+ sint32 value = poffGetPcForDefinedLabel(pDebugInfo->value);
+ if (value >= 0)
+ {
+ /* Yes... replace the label reference with a text section offset. */
+
+ pDebugInfo->value = value;
+ }
+ else
+ {
+ fatal(ePOFFCONFUSION);
+ }
+ }
+
+ /* Then put all of the debug info back into the POFF object */
+
+ poffDiscardDebugFuncInfo(poffHandle);
+
+ for (pDebugInfo = pDebugInfoHead; pDebugInfo; pDebugInfo = pDebugInfo->next)
+ {
+ poffAddDebugFuncInfo(poffHandle, pDebugInfo);
+ }
+
+ /* Release the bufferred debug information */
+
+ pDebugInfo = pDebugInfoHead;
+ while (pDebugInfo)
+ {
+ pNextDebugInfo = pDebugInfo->next;
+ poffReleaseDebugFuncContainer(pDebugInfo);
+ pDebugInfo = pNextDebugInfo;
+ }
+}
+
+/**********************************************************************/
+
+static void pass5(poffHandle_t poffHandle)
+{
+ uint32 entryLabel;
+ sint32 entryOffset;
+ ubyte fileType;
+
+ /* What kind of a file did we just process. Was it a program file?
+ * or was it a unit file?
+ */
+
+ fileType = poffGetFileType(poffHandle);
+ if (fileType == FHT_PROGRAM)
+ {
+ /* It is a program file. In this case, it must have a valid
+ * entry point label. Get it.
+ */
+
+ entryLabel = poffGetEntryPoint(poffHandle);
+
+ /* Convert the label into a program data section offset */
+
+ entryOffset = poffGetPcForDefinedLabel(entryLabel);
+ if (entryOffset < 0)
+ {
+ fatal(ePOFFCONFUSION);
+ }
+
+ /* Replace file header entry point with the program data
+ * section offset
+ */
+
+ poffSetEntryPoint(poffHandle, entryOffset);
+ }
+}
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+void optFinalize(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ /* Build label / line number reference table */
+
+ pass1(poffHandle, poffProgHandle);
+
+ /* Reset for next pass */
+
+ insn_ResetOpCodeRead(poffHandle);
+ insn_ResetTmpOpCodeWrite(poffProgHandle);
+
+ /* Now process all of the symbols */
+
+ pass2(poffHandle, poffProgHandle);
+
+ /* Reset for next pass */
+
+ insn_ResetOpCodeRead(poffHandle);
+
+ /* Generate relocation information and replace all label references
+ * in the code with actual program section data offsets.
+ */
+
+ pass3(poffHandle, poffProgHandle);
+
+ /* Fixed label references in the debug function information */
+
+ pass4(poffHandle);
+
+ /* Reset for next pass */
+
+ insn_ResetOpCodeRead(poffHandle);
+ insn_ResetTmpOpCodeWrite(poffProgHandle);
+
+ /* Finally, replace file header entry point with the I-space offset */
+
+ pass5(poffHandle);
+
+ /* Clean up after ourselves */
+
+ poffReleaseLabelReferences();
+}
+
+/**********************************************************************/
diff --git a/misc/pascal/insn32/popt/pfopt.h b/misc/pascal/insn32/popt/pfopt.h
new file mode 100644
index 0000000000..d792d11bff
--- /dev/null
+++ b/misc/pascal/insn32/popt/pfopt.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * pfopt.h
+ * External Declarations associated with pfopt.c
+ *
+ * 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.
+ *
+ ***************************************************************************/
+
+#ifndef __PFOPT_H
+#define __PFOPT_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "pofflib.h"
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void optFinalize(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle);
+
+#endif /* __PFOPT_H */
+
diff --git a/misc/pascal/insn32/popt/pjopt.c b/misc/pascal/insn32/popt/pjopt.c
new file mode 100644
index 0000000000..c10962d3c3
--- /dev/null
+++ b/misc/pascal/insn32/popt/pjopt.c
@@ -0,0 +1,449 @@
+/**********************************************************************
+ * pjopt.c
+ * Branch 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 "popt.h"
+#include "polocal.h"
+#include "pjopt.h"
+
+/**********************************************************************/
+
+int BranchOptimize (void)
+{
+ int nchanges = 0;
+ register int i;
+
+ TRACE(stderr, "[BranchOptimize]");
+
+ /* At least two pcodes are need to perform branch optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ switch (pptr[i]->op)
+ {
+ case oNOT :
+ switch (pptr[i+1]->op)
+ {
+ case oJEQUZ :
+ pptr[i+1]->op = oJNEQZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJEQUZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oNEG :
+ switch (pptr[i+1]->op)
+ {
+ case oJLTZ :
+ pptr[i+1]->op = oJGTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJGTEZ :
+ pptr[i+1]->op = oJLTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJGTZ :
+ pptr[i+1]->op = oJLTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJLTEZ :
+ pptr[i+1]->op = oJGTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oEQU :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oNEQ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJNEQ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJEQU;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oNEQ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oEQU;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJEQU;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJNEQ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLT :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGTE;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGTE :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLT;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGT :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLTE;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLTE :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGT;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGT;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLTE;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oEQUZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oNEQZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJNEQZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJEQUZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oNEQZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oEQUZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ case oJNEQZ :
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLTZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGTEZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGTEZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLTZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oGTZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oLTEZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJLTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJGTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ case oLTEZ :
+ switch (pptr[i+1]->op)
+ {
+ case oNOT :
+ pptr[i]->op = oGTZ;
+ deletePcode(i+1);
+ nchanges++;
+ break;
+
+ case oJEQUZ :
+ pptr[i+1]->op = oJGTZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ case oJNEQZ :
+ pptr[i+1]->op = oJLTEZ;
+ deletePcode(i);
+ nchanges++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end while */
+ return (nchanges);
+
+} /* end BranchOptimize */
+
+/**********************************************************************/
+
diff --git a/misc/pascal/insn32/popt/pjopt.h b/misc/pascal/insn32/popt/pjopt.h
new file mode 100644
index 0000000000..4564ec6c6c
--- /dev/null
+++ b/misc/pascal/insn32/popt/pjopt.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * pjopt.h
+ * External Declarations associated with pjopt.c
+ *
+ * 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.
+ *
+ ***************************************************************************/
+
+#ifndef __PJOPT_H
+#define __PJOPT_H
+
+extern int BranchOptimize ( void );
+
+#endif __PJOPT_H
+
+
diff --git a/misc/pascal/insn32/popt/plopt.c b/misc/pascal/insn32/popt/plopt.c
new file mode 100644
index 0000000000..d58f1a5548
--- /dev/null
+++ b/misc/pascal/insn32/popt/plopt.c
@@ -0,0 +1,214 @@
+/**********************************************************************
+ * plopt.c
+ * Load/Store 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 "popt.h"
+#include "polocal.h"
+#include "plopt.h"
+
+/**********************************************************************/
+
+int LoadOptimize(void)
+{
+ uint32 val;
+ int nchanges = 0;
+ register int i;
+
+ TRACE(stderr, "[LoadOptimize]");
+
+ /* At least two pcodes are need to perform Load optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ switch (GETOP(pptr[i]))
+ {
+ /* Eliminate duplicate loads */
+
+ case oLDSH :
+ if ((GETOP(pptr[i+1]) == oLDSH) &&
+ (GETARG(pptr[i+1]) == GETARG(pptr[i])))
+ {
+ PUTOP(pptr[i+1], oDUP);
+ PUTARG(pptr[i+1], 0);
+ nchanges++;
+ i += 2;
+ } /* end if */
+ else i++;
+ break;
+
+ /* Convert loads indexed by a constant to unindexed loads */
+
+ case oPUSH :
+ /* Get the index value */
+
+ val = (sint32)GETARG(pptr[i]);
+
+ /* If the following instruction is a load, add the constant
+ * index value to the address and switch the opcode to the
+ * unindexed form.
+ */
+
+ if (GETOP(pptr[i+1]) == oLDSXH)
+ {
+ PUTOP(pptr[i+1], oLDSH);
+ val += GETARG(pptr[i+1]);
+ PUTARG(pptr[i+1], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (GETOP(pptr[i+1]) == oLASX)
+ {
+ PUTOP(pptr[i+1], oLAS);
+ val += GETARG(pptr[i+1]);
+ PUTARG(pptr[i+1], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end else if */
+ else if (GETOP(pptr[i+1]) == oLDSXB)
+ {
+ PUTOP(pptr[i+1], oLDSB);
+ val += GETARG(pptr[i+1]);
+ PUTARG(pptr[i+1], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (GETOP(pptr[i+1]) == oLDSXM)
+ {
+ PUTOP(pptr[i+1], oLDSM);
+ val += GETARG(pptr[i+1]);
+ PUTARG(pptr[i+1], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end while */
+ return (nchanges);
+} /* end LoadOptimize */
+
+/**********************************************************************/
+int StoreOptimize (void)
+{
+ uint32 val;
+ int nchanges = 0;
+ register int i;
+
+ TRACE(stderr, "[StoreOptimize]");
+
+ /* At least two pcodes are need to perform the following Store */
+ /* optimizations */
+
+ i = 0;
+ while (i < nops-1)
+ {
+ switch (GETOP(pptr[i]))
+ {
+ /* Eliminate store followed by load */
+
+ case oSTSH :
+ if ((GETOP(pptr[i+1]) == oLDSH) &&
+ (GETARG(pptr[i+1]) == GETARG(pptr[i])))
+ {
+ PUTOP(pptr[i+1], oSTSH);
+ PUTOP(pptr[i], oDUP);
+ PUTARG(pptr[i], 0);
+ nchanges++;
+ i += 2;
+ } /* end if */
+ else i++;
+ break;
+
+ /* Convert stores indexed by a constant to unindexed stores */
+ case oPUSH :
+ /* Get the index value */
+
+ val = (sint32)GETARG(pptr[i]);
+
+ /* If the following instruction is a store, add the constant
+ * index value to the address and switch the opcode to the
+ * unindexed form.
+ */
+
+ if (i < nops-2)
+ {
+ if (GETOP(pptr[i+2]) == oSTSXH)
+ {
+ PUTOP(pptr[i+2], oSTSH);
+ val += GETARG(pptr[i+2]);
+ PUTARG(pptr[i+2], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else if (GETOP(pptr[i+2]) == oSTSXB)
+ {
+ PUTOP(pptr[i+2], oSTSB);
+ val += GETARG(pptr[i+2]);
+ PUTARG(pptr[i+2], val);
+ deletePcode (i);
+ nchanges++;
+ } /* end if */
+ else i++;
+ } /* end if */
+ else i++;
+ break;
+
+ default :
+ i++;
+ break;
+ } /* end switch */
+ } /* end while */
+
+ return (nchanges);
+
+} /* end StoreOptimize */
+
+/**********************************************************************/
+
diff --git a/misc/pascal/insn32/popt/plopt.h b/misc/pascal/insn32/popt/plopt.h
new file mode 100644
index 0000000000..05596cd45f
--- /dev/null
+++ b/misc/pascal/insn32/popt/plopt.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * plopt.h
+ * External Declarations associated with plopt.c
+ *
+ * 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.
+ *
+ ***************************************************************************/
+
+#ifndef __PLOPT_H
+#define __PLOPT_H
+
+extern int LoadOptimize ( void );
+extern int StoreOptimize ( void );
+
+#endif /* __PLOPT_H */
diff --git a/misc/pascal/insn32/popt/polocal.c b/misc/pascal/insn32/popt/polocal.c
new file mode 100644
index 0000000000..551913a490
--- /dev/null
+++ b/misc/pascal/insn32/popt/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();
+}
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/popt/polocal.h b/misc/pascal/insn32/popt/polocal.h
new file mode 100644
index 0000000000..a46e4dc9c5
--- /dev/null
+++ b/misc/pascal/insn32/popt/polocal.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * polocal.h
+ * External Declarations associated with polocal.c
+ *
+ * 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.
+ *
+ ***************************************************************************/
+
+#ifndef __POLOCAL_H
+#define __POLOCAL_H
+
+/***************************************************************************
+* Included Files
+****************************************************************************/
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pofflib.h"
+
+/***************************************************************************
+* Definitions
+****************************************************************************/
+
+#define WINDOW 10 /* size of optimization window */
+
+/***************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+
+extern void localOptimization(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle);
+extern void deletePcode (int delIndex);
+extern void deletePcodePair (int delIndex1, int delIndex2);
+
+/***************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+extern OPTYPE ptable [WINDOW]; /* Pcode Table */
+extern OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */
+
+extern int nops; /* No. Valid Pcode Pointers */
+extern int end_out; /* 1 = oEND pcode has been output */
+
+#endif /* __PLOCAL_H */
diff --git a/misc/pascal/insn32/popt/popt.c b/misc/pascal/insn32/popt/popt.c
new file mode 100644
index 0000000000..cf8c76ce34
--- /dev/null
+++ b/misc/pascal/insn32/popt/popt.c
@@ -0,0 +1,327 @@
+/**********************************************************************
+ * popt.c
+ * P-Code Optimizer Main Logic
+ *
+ * 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 <stdlib.h>
+#include <unistd.h>
+
+#include "keywords.h"
+#include "podefs.h"
+#include "paslib.h"
+#include "pofflib.h"
+
+#include "pinsn.h"
+#include "popt.h"
+#include "psopt.h"
+#include "polocal.h"
+#include "pfopt.h"
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static void showUsage (const char *progname, int errcode);
+static void readPoffFile (const char *filename);
+static void pass1 (void);
+static void pass2 (void);
+static void pass3 (void);
+static void writePoffFile (const char *filename);
+
+/**********************************************************************
+ * Global Variables
+ **********************************************************************/
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static poffHandle_t poffHandle; /* Handle to POFF object */
+static int no_resolve = 0;
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+int main(int argc, char *argv[], char *envp[])
+{
+ const char *outfilename;
+ TRACE(stderr, "[main]");
+ int option;
+
+ /* Process command line argruments */
+
+ while ((option = getopt(argc, argv, "rh")) > 0)
+ {
+ switch (option)
+ {
+ case 'r' :
+ no_resolve++;
+ break;
+ case 'h' :
+ showUsage(argv[0], 0);
+ default:
+ fprintf(stderr, "Unrecognized option\n");
+ showUsage(argv[0], -1);
+ }
+ }
+
+ /* Check for existence of filename argument */
+
+ if (optind != argc - 1)
+ {
+ printf("Filename required at end of command line.\n");
+ showUsage(argv[0], -1);
+ } /* end if */
+
+ /* Read the POFF file into memory */
+
+ outfilename = argv[optind];
+ readPoffFile(outfilename);
+
+ /* Performs pass1 optimization */
+
+ pass1();
+
+ /* Performs pass2 optimization */
+
+ insn_ResetOpCodeRead(poffHandle);
+ pass2();
+
+ if (!no_resolve)
+ {
+ /* Create final section offsets and relocation entries */
+
+ insn_ResetOpCodeRead(poffHandle);
+ pass3();
+ }
+
+ /* Write the POFF file */
+
+ writePoffFile(outfilename);
+ return 0;
+
+} /* End main */
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void showUsage(const char *progname, int errcode)
+{
+ fprintf(stderr, "USAGE:\n");
+ fprintf(stderr, " %s -h\n", progname);
+ fprintf(stderr, " %s [-r] <poff-filename>\n", progname);
+ fprintf(stderr, "WHERE:\n");
+ fprintf(stderr, " -r: Disables label resolution (default: labels resolved)\n");
+ fprintf(stderr, " -h: Shows this message\n");
+ exit(errcode);
+}
+
+/***********************************************************************/
+
+static void readPoffFile(const char *filename)
+{
+ char objname [FNAME_SIZE+1];
+ FILE *objFile;
+ int errcode;
+
+ TRACE(stderr, "[readPoffFile]");
+
+ /* Open the pass1 POFF object file -- Use .o1 extension */
+
+ (void)extension(filename, "o1", objname, 1);
+ if (!(objFile = fopen(objname, "rb")))
+ {
+ printf("Error Opening %s\n", objname);
+ exit(1);
+ } /* end if */
+
+ /* Get a handle to a POFF input object */
+
+ poffHandle = poffCreateHandle();
+ if (!poffHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Read the POFF file into memory */
+
+ errcode = poffReadFile(poffHandle, objFile);
+ if (errcode != 0)
+ {
+ printf("Could not read POFF file, errcode=0x%02x\n", errcode);
+ exit(1);
+ }
+
+ /* Close the input file */
+
+ fclose(objFile);
+} /* end pass1 */
+
+/***********************************************************************/
+
+static void pass1(void)
+{
+ poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */
+
+ TRACE(stderr, "[pass1]");
+
+ /* Create a handle to a temporary object to store new POFF program
+ * data.
+ */
+
+ poffProgHandle = poffCreateProgHandle();
+ if (!poffProgHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Clean up garbage left from the wasteful string stack logic */
+
+ stringStackOptimize(poffHandle, poffProgHandle);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+
+ /* Release the temporary POFF object */
+
+ poffDestroyProgHandle(poffProgHandle);
+} /* end pass1 */
+
+/***********************************************************************/
+
+static void pass2(void)
+{
+ poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */
+
+ TRACE(stderr, "[pass2]");
+
+ /* Create a handle to a temporary object to store new POFF program
+ * data.
+ */
+
+ poffProgHandle = poffCreateProgHandle();
+ if (!poffProgHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Perform Local Optimizatin Initialization */
+
+ localOptimization(poffHandle, poffProgHandle);
+
+ /* Replace the original program data with the new program data */
+
+ poffReplaceProgData(poffHandle, poffProgHandle);
+
+ /* Release the temporary POFF object */
+
+ poffDestroyProgHandle(poffProgHandle);
+} /* end pass2 */
+
+/***********************************************************************/
+
+static void pass3 (void)
+{
+ poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */
+ TRACE(stderr, "[pass3]");
+
+ /* Create a handle to a temporary object to store new POFF program
+ * data.
+ */
+
+ poffProgHandle = poffCreateProgHandle();
+ if (!poffProgHandle)
+ {
+ printf("Could not get POFF handle\n");
+ exit(1);
+ } /* end if */
+
+ /* Finalize program section, create relocation and line number
+ * sections.
+ */
+
+ optFinalize(poffHandle, poffProgHandle);
+
+ /* Release the temporary POFF object */
+
+ poffDestroyProgHandle(poffProgHandle);
+}
+
+/***********************************************************************/
+
+static void writePoffFile(const char *filename)
+{
+ char optname [FNAME_SIZE+1];
+ FILE *optFile;
+
+ TRACE(stderr, "[writePoffFile]");
+
+ /* Open optimized p-code file -- Use .o extension */
+
+ (void)extension(filename, "o", optname, 1);
+ if (!(optFile = fopen(optname, "wb")))
+ {
+ printf("Error Opening %s\n", optname);
+ exit(1);
+ } /* end if */
+
+ /* Then write the new POFF file */
+
+ poffWriteFile(poffHandle, optFile);
+
+ /* Destroy the POFF object */
+
+ poffDestroyHandle(poffHandle);
+
+ /* Close the files used on writePoffFile */
+
+ (void)fclose(optFile);
+} /* end writePoffFile */
+
+/***********************************************************************/
diff --git a/misc/pascal/insn32/popt/popt.h b/misc/pascal/insn32/popt/popt.h
new file mode 100644
index 0000000000..9cd151a89d
--- /dev/null
+++ b/misc/pascal/insn32/popt/popt.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ * popt.h
+ * External Declarations associated with popt.c
+ *
+ * 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.
+ *
+ ***************************************************************************/
+
+#ifndef __POPT_H
+#define __POPT_H
+
+/***************************************************************************
+* Included Files
+****************************************************************************/
+
+/***************************************************************************
+ * Global Variables
+ ****************************************************************************/
+
+/***************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+
+#endif /* __POPT_H */
diff --git a/misc/pascal/insn32/popt/psopt.c b/misc/pascal/insn32/popt/psopt.c
new file mode 100644
index 0000000000..6794115c83
--- /dev/null
+++ b/misc/pascal/insn32/popt/psopt.c
@@ -0,0 +1,384 @@
+/**********************************************************************
+ * psopt.c
+ * String Stack Optimizaitons
+ *
+ * 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.
+ *
+ **********************************************************************/
+
+/* The statement generation logic generates a PUSHS and POPS around
+ * every statement. These instructions save and restore the string
+ * stack pointer registers. However, only some statements actually
+ * modify the string stack. So the first major step in the optimatization
+ * process is to retain only PUSHS and POPS statements that are
+ * actually required.
+ */
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "keywords.h"
+#include "pdefs.h"
+#include "pedefs.h"
+#include "pinsn32.h"
+#include "pxdefs.h"
+
+#include "popt.h"
+#include "psopt.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define PBUFFER_SIZE 1024
+#define NPBUFFERS 8
+
+/**********************************************************************
+ * Private Data
+ **********************************************************************/
+
+static ubyte *pbuffer[NPBUFFERS];
+static int nbytes_in_pbuffer[NPBUFFERS];
+static int current_level = -1;
+static int inch;
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+static inline void putbuf(int c, poffProgHandle_t poffProgHandle);
+static inline void flushc(int c, poffProgHandle_t poffProgHandle);
+static inline void flushbuf(poffProgHandle_t poffProgHandle);
+static void dopush(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle);
+static void dopop(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle);
+
+/**********************************************************************
+ * Private Inline Functions
+ **********************************************************************/
+
+static inline void putbuf(int c, poffProgHandle_t poffProgHandle)
+{
+ int dlvl = current_level;
+
+ if (dlvl < 0)
+ {
+ /* No PUSHS encountered. Write byte directly to output */
+
+ poffAddTmpProgByte(poffProgHandle, (ubyte)c);
+ }
+ else
+ {
+ /* PUSHS encountered. Write byte into buffer associated with
+ * nesting level.
+ */
+
+ int idx = nbytes_in_pbuffer[dlvl];
+ ubyte *dest = pbuffer[dlvl] + idx;
+ *dest = c;
+ nbytes_in_pbuffer[dlvl] = idx + 1;
+ }
+}
+
+static inline void flushc(int c, poffProgHandle_t poffProgHandle)
+{
+ if (current_level > 0)
+ {
+ /* Nested PUSHS encountered. Write byte into buffer associated
+ * with the previous nesting level.
+ */
+
+ int dlvl = current_level - 1;
+ int idx = nbytes_in_pbuffer[dlvl];
+ ubyte *dest = pbuffer[dlvl] + idx;
+ *dest = c;
+ nbytes_in_pbuffer[dlvl] = idx + 1;
+ }
+ else
+ {
+ /* Only one PUSHS encountered. Write directly to the output
+ * buffer
+ */
+
+ poffAddTmpProgByte(poffProgHandle, (ubyte)c);
+ }
+}
+
+static inline void flushbuf(poffProgHandle_t poffProgHandle)
+{
+ int errCode;
+ int slvl = current_level;
+
+ if (nbytes_in_pbuffer[slvl] > 0)
+ {
+ if (current_level > 0)
+ {
+ /* Nested PUSHS encountered. Flush buffer into buffer associated
+ * with the previous nesting level.
+ */
+
+ int dlvl = slvl - 1;
+ ubyte *src = pbuffer[slvl];
+ ubyte *dest = pbuffer[dlvl] + nbytes_in_pbuffer[dlvl];
+
+ memcpy(dest, src, nbytes_in_pbuffer[slvl]);
+ nbytes_in_pbuffer[dlvl] += nbytes_in_pbuffer[slvl];
+ }
+ else
+ {
+ /* Only one PUSHS encountered. Flush directly to the output
+ * buffer
+ */
+
+ errCode = poffWriteTmpProgBytes(pbuffer[0], nbytes_in_pbuffer[0],
+ poffProgHandle);
+
+ if (errCode != eNOERROR)
+ {
+ printf("Error writing to file: %d\n", errCode);
+ exit(1);
+ }
+ }
+ }
+ nbytes_in_pbuffer[slvl] = 0;
+}
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+static void dopush(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ int opcode;
+
+ while (inch != EOF)
+ {
+ /* Search for a PUSHS opcode */
+
+ if (inch != oPUSHS)
+ {
+ /* Its not PUSHS, just echo to the output file/buffer */
+
+ putbuf(inch, poffProgHandle);
+
+ /* Get the next byte from the input stream */
+
+ opcode = inch;
+ inch = poffGetProgByte(poffHandle);
+
+ /* Check for a 32-bit argument */
+
+ if ((opcode & o32) != 0)
+ {
+ /* Echo the 32-bits of the argument */
+
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ }
+ }
+ else
+ {
+ /* We have found PUSHS. No search for the next occurrence
+ * of either and instruction that increments the string
+ * stack or for the matching POPS
+ */
+
+ current_level++;
+ dopop(poffHandle, poffProgHandle);
+ current_level--;
+ }
+ }
+}
+
+static void dopop(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle)
+{
+ /* We have found PUSHS. No search for the next occurrence
+ * of either and instruction that increments the string
+ * stack or for the matching POPS
+ */
+
+ /* Skip over the PUSHS for now */
+
+ inch = poffGetProgByte(poffHandle);
+
+ while (inch != EOF)
+ {
+ /* Did we encounter another PUSHS? */
+
+ if (inch == oPUSHS)
+ {
+ /* Yes... recurse to handle it */
+
+ current_level++;
+ dopop(poffHandle, poffProgHandle);
+ current_level--;
+ }
+
+ else if (inch == oPOPS)
+ {
+ /* Flush the buffered data without the PUSHS */
+
+ flushbuf(poffProgHandle);
+
+ /* And discard the matching POPS */
+
+ inch = poffGetProgByte(poffHandle);
+ break;
+ }
+ else if (inch == oLIB)
+ {
+ uint32 arg32;
+ unsigned int tmp;
+
+ /* Get the 32-bit argument from the big endian data stream */
+
+ tmp = poffGetProgByte(poffHandle);
+ arg32 = tmp << 24;
+ putbuf(tmp, poffProgHandle);
+
+ tmp = poffGetProgByte(poffHandle);
+ arg32 |= tmp << 16;
+ putbuf(tmp, poffProgHandle);
+
+ tmp = poffGetProgByte(poffHandle);
+ arg32 |= tmp << 8;
+ putbuf(tmp, poffProgHandle);
+
+ tmp = poffGetProgByte(poffHandle);
+ arg32 |= tmp;
+ putbuf(tmp, poffProgHandle);
+
+ inch = poffGetProgByte(poffHandle);
+
+ /* Is it LIB MKSTK? MKSTKSTR? or MKSTKC? */
+
+ if ((arg32 == lbMKSTK) ||
+ (arg32 == lbMKSTKSTR) ||
+ (arg32 == lbMKSTKC))
+ {
+ /* Flush the buffered data with the PUSHS */
+
+ flushc(oPUSHS, poffProgHandle);
+ flushbuf(poffProgHandle);
+
+ /* And break out of the loop to search for
+ * the next PUSHS
+ */
+
+ break;
+ }
+ }
+ else
+ {
+ int opcode;
+
+ /* Something else. Put it in the buffer */
+
+ putbuf(inch, poffProgHandle);
+
+ /* Get the next byte from the input stream */
+
+ opcode = inch;
+ inch = poffGetProgByte(poffHandle);
+
+ /* Check for a 32-bit argument */
+
+ if (opcode & o32 != 0)
+ {
+ /* Buffer the remaining 24-bits of the argument */
+
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ putbuf(inch, poffProgHandle);
+ inch = poffGetProgByte(poffHandle);
+ }
+ }
+ }
+}
+
+/**********************************************************************
+ * Global Functions
+ **********************************************************************/
+
+void stringStackOptimize(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle)
+{
+ int i;
+
+ /* Allocate an array of buffers to hold pcode data */
+
+ for (i = 0; i < NPBUFFERS; i++)
+ {
+ pbuffer[i] = (ubyte*)malloc(PBUFFER_SIZE);
+ if (pbuffer[i] == NULL)
+ {
+ printf("Failed to allocate pcode buffer\n");
+ exit(1);
+ }
+ nbytes_in_pbuffer[i] = 0;
+ }
+
+ /* Prime the search logic */
+
+ inch = poffGetProgByte(poffHandle);
+ current_level = -1;
+
+ /* And parse the input file to the output file, removing unnecessary string
+ * stack operations.
+ */
+
+ dopush(poffHandle, poffProgHandle);
+
+ /* Release the buffers */
+
+ for (i = 0; i < NPBUFFERS; i++)
+ {
+ free(pbuffer[i]);
+ pbuffer[i] = NULL;
+ nbytes_in_pbuffer[i] = 0;
+ }
+}
+
+/**********************************************************************/
diff --git a/misc/pascal/insn32/popt/psopt.h b/misc/pascal/insn32/popt/psopt.h
new file mode 100644
index 0000000000..c174aac8ea
--- /dev/null
+++ b/misc/pascal/insn32/popt/psopt.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * psopt.h
+ * External Declarations associated with psopt.c
+ *
+ * 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.
+ *
+ ***************************************************************************/
+
+#ifndef __PSOPT_H
+#define __PSOPT_H
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include "pofflib.h"
+
+/***************************************************************************
+ * Global Function Prototypes
+ ***************************************************************************/
+
+extern void stringStackOptimize(poffHandle_t poffHandle,
+ poffProgHandle_t poffProgHandle);
+
+#endif /* __PSOPT_H */
+