From 21c3157d82c5ff56651df5317153f4ffc1e2b942 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 5 Jan 2008 16:43:27 +0000 Subject: P-code optimizer git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@506 42af7a65-404d-4744-a932-0658087f49c3 --- misc/pascal/insn32/popt/Makefile | 93 +++++ misc/pascal/insn32/popt/pcopt.c | 839 ++++++++++++++++++++++++++++++++++++++ misc/pascal/insn32/popt/pcopt.h | 47 +++ misc/pascal/insn32/popt/pfopt.c | 543 ++++++++++++++++++++++++ misc/pascal/insn32/popt/pfopt.h | 54 +++ misc/pascal/insn32/popt/pjopt.c | 449 ++++++++++++++++++++ misc/pascal/insn32/popt/pjopt.h | 44 ++ misc/pascal/insn32/popt/plopt.c | 214 ++++++++++ misc/pascal/insn32/popt/plopt.h | 43 ++ misc/pascal/insn32/popt/polocal.c | 271 ++++++++++++ misc/pascal/insn32/popt/polocal.h | 73 ++++ misc/pascal/insn32/popt/popt.c | 327 +++++++++++++++ misc/pascal/insn32/popt/popt.h | 52 +++ misc/pascal/insn32/popt/psopt.c | 384 +++++++++++++++++ misc/pascal/insn32/popt/psopt.h | 54 +++ 15 files changed, 3487 insertions(+) create mode 100644 misc/pascal/insn32/popt/Makefile create mode 100644 misc/pascal/insn32/popt/pcopt.c create mode 100644 misc/pascal/insn32/popt/pcopt.h create mode 100644 misc/pascal/insn32/popt/pfopt.c create mode 100644 misc/pascal/insn32/popt/pfopt.h create mode 100644 misc/pascal/insn32/popt/pjopt.c create mode 100644 misc/pascal/insn32/popt/pjopt.h create mode 100644 misc/pascal/insn32/popt/plopt.c create mode 100644 misc/pascal/insn32/popt/plopt.h create mode 100644 misc/pascal/insn32/popt/polocal.c create mode 100644 misc/pascal/insn32/popt/polocal.h create mode 100644 misc/pascal/insn32/popt/popt.c create mode 100644 misc/pascal/insn32/popt/popt.h create mode 100644 misc/pascal/insn32/popt/psopt.c create mode 100644 misc/pascal/insn32/popt/psopt.h (limited to 'misc') diff --git a/misc/pascal/insn32/popt/Makefile b/misc/pascal/insn32/popt/Makefile new file mode 100644 index 000000000..5670a6a3d --- /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 +# +# 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 000000000..ee5f4d924 --- /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 + * + * 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 + +#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 000000000..f638fcf28 --- /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 + * + * 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 000000000..de07400bf --- /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 + * + * 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 +#include +#include + +#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 000000000..d792d11bf --- /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 + * + * 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 000000000..c10962d3c --- /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 + * + * 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 + +#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 000000000..4564ec6c6 --- /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 + * + * 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 000000000..d58f1a554 --- /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 + * + * 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 + +#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 000000000..05596cd45 --- /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 + * + * 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 000000000..551913a49 --- /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 + * + * 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 + +#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 000000000..a46e4dc9c --- /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 + * + * 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 000000000..cf8c76ce3 --- /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 + * + * 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 +#include +#include + +#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] \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 000000000..9cd151a89 --- /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 + * + * 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 000000000..6794115c8 --- /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 + * + * 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 +#include +#include + +#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 000000000..c174aac8e --- /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 + * + * 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 */ + -- cgit v1.2.3