Resync new repository with old repo r5166

git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5153 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2012-09-17 18:18:44 +00:00
commit 57623d42eb
5691 changed files with 1361853 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
############################################################################
# insn16/Makefile
#
# Copyright (C) 2008 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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
#
INSNDIR = ${shell pwd}
PASCAL = $(INSNDIR)/..
include $(PASCAL)/Make.config
include $(PASCAL)/Make.defs
LIBDIR = $(PASCAL)/lib
BINDIR = $(PASCAL)/bin16
LIBINSNDIR = $(INSNDIR)/libinsn
POPTDIR = $(INSNDIR)/popt
PRUNDIR = $(INSNDIR)/prun
PLISTDIR = $(INSNDIR)/plist
#
# Objects and targets
#
all: libinsn popt prun plist
PHONY: all libinsn popt prun plist clean
$(LIBINSNDIR)/libinsn.a:
$(MAKE) -C $(LIBINSNDIR)
libinsn.a: $(LIBINSNDIR)/libinsn.a
$(BINDIR)/popt:
$(MAKE) -C $(POPTDIR)
popt: $(BINDIR)/popt
$(BINDIR)/prun:
$(MAKE) -C $(PRUNDIR)
prun: $(BINDIR)/prun
$(BINDIR)/plist:
$(MAKE) -C $(PLISTDIR)
plist: $(BINDIR)/plist
clean:
$(RM) libinsn.a core *~
$(MAKE) -C $(LIBINSNDIR) clean
$(MAKE) -C $(POPTDIR) clean
$(MAKE) -C $(PRUNDIR) clean
$(MAKE) -C $(PLISTDIR) clean
@@ -0,0 +1,239 @@
P-Code optimizations:
Let <push-ops> be oPUSH|oPUSHB
Let <load-ops> be oLOD|oLODB|PUSH|oLADR|oLCADR
pcopt.c:unaryOptimize
STEP 1:
Remove unary operators on constants:
<push-op> arg + oNEG -> <push-op> arg
<push-op> arg + oABS -> <push-op> |arg|
<push-op> arg + oINC -> <push-op> arg+1
<push-op> arg + oDEC -> <push-op> arg-1
<push-op> arg + oNOT -> <push-op> ~arg
Simplify binary operations on constants
<push-op> arg + oADD
if arg == 0 -> delete both
else if arg == 1 -> oINC
else if arg == -1 -> oDEC
<push-op> arg + oSUB
if arg == 0 -> delete both
else if arg == 1 -> oDEC
else if arg == -1 -> oINC
<push-op> arg + oMUL
if arg is power of 2 -> oSLL power
<push-op> arg + oDIV
if arg is power of 2 -> oSRA power
<push-op> arg + oSLL
if arg is 0 -> <push-op> arg
<push-op> arg + oSRL
if arg is 0 -> <push-op> arg
<push-op> arg + oSRA
if arg is 0 -> <push-op> arg
<push-op> arg + oOR
if arg is 0 -> <push-op> arg
<push-op> arg + oAND
if arg is 0xffff -> <push-op> arg
Delete comparisons with zero
<push-op> arg + oEQUZ
if arg == 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oNEQZ
if arg != 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oLTZ
if arg < 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oGTEZ
if arg >= 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oGTZ
if arg > 0 -> <push-op> true
else -> <push-op> false
<push-op> arg + oLTEZ
if arg <= 0 -> <push-op> true
else -> <push-op> false
Simplify comparisons with certain constants
<push-op> arg + oEQU
if arg == 0 -> oEQUZ
else if arg == 1 -> oDEC + oEQUZ
else if arg == -1 -> oINC + oEQUZ
<push-op> arg + oNEQ
if arg == 0 -> oNEQZ
else if arg == 1 -> oDEC + oNEQZ
else if arg == -1 -> oINC + oNEQZ
<push-op> arg + oLT
if arg == 0 -> oLTZ
else if arg == 1 -> oDEC + oLTZ
else if arg == -1 -> oINC + oLTZ
<push-op> arg + oGTE
if arg == 0 -> oGTEZ
else if arg == 1 -> oDEC + oGTEZ
else if arg == -1 -> oINC + oGTEZ
<push-op> arg + oGT
if arg == 0 -> oGTZ
else if arg == 1 -> oDEC + oGTZ
else if arg == -1 -> oINC + oGTZ
<push-op> arg + oLTE
if arg == 0 -> oLTEZ
else if arg == 1 -> oDEC + oLTEZ
else if arg == -1 -> oINC + oLTEZ
Simplify or delete condition branches on constants
<push-op> arg + oJEQUZ
if arg == 0 -> oJMP
else -> delete both
<push-op> arg + oJNEQZ
if arg != 0 -> oJMP
else -> delete both
<push-op> arg + oJLTZ
if arg < 0 -> oJMP
else -> delete both
<push-op> arg + oJGTEZ
if arg >= 0 -> oJMP
else -> delete both
<push-op> arg + oJGTZ
if arg > 0 -> oJMP
else -> delete both
<push-op> arg + oJLTEZ
if arg <= 0 -> oJMP
else -> delete both
STEP 1a:
<push-op> arg
if arg < 256 -> oPUSHB arg
else -> oPUSH arg
STEP 2:
Delete multiple modifications of DSEG pointer
INDS arg1 + INDS arg2 -> INDS arg1+arg2
pcopt.c:binaryOptimize
STEP 1:
<push-op> arg1 + <push-op> arg2 + oADD -> oPUSH arg1 + arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oSUB -> oPUSH arg1 - arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oMUL -> oPUSH arg1 * arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oDIV -> oPUSH arg1 / arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oMOD -> oPUSH arg1 % arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oSLL -> oPUSH arg1 << arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oSRL -> oPUSH arg1 >> arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oSRA -> oPUSH arg1 >> arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oOR -> oPUSH arg1 | arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oAND -> oPUSH arg1 & arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oEQU -> oPUSH arg1 == arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oNEQ -> oPUSH arg1 != arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oLT -> oPUSH arg1 < arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oGTE -> oPUSH arg1 >= arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oGT -> oPUSH arg1 > arg2 + STEP 1a
<push-op> arg1 + <push-op> arg2 + oLTE -> oPUSH arg1 <= arg2 + STEP 1a
STEP 1a:
<push-op> arg
if arg < 256 -> oPUSHB arg
else -> oPUSH arg
STEP 2:
<push-op> arg1 + <load-ops> arg2 + oADD
if arg1 == 0 -> <load-ops> arg
else if arg1 == 1 -> <load-ops> arg + oINC
else if arg1 == -1 -> <load-ops> arg + oDEC
<push-op> arg1 + <load-ops> arg2 + oSUB
if arg1 == 0 -> <load-ops> arg + oNEG
<push-op> arg1 + <load-ops> arg2 + oMUL -> <load-ops> arg + oSLL log
if arg is a power of 2
<push-op> arg1 + <load-ops> arg2 + oOR
if arg1 == 0 -> <load-ops> arg
<push-op> arg1 + <load-ops> arg2 + oAND
if arg1 == 0xffff -> <load-ops> arg
<push-op> arg1 + <load-ops> arg2 + oEQU
if arg1 == 0 -> <load-ops> arg + oEQUZ
<push-op> arg1 + <load-ops> arg2 + oNEQ
if arg1 == 0 -> <load-ops> arg + oNEQZ
<push-op> arg1 + <load-ops> arg2 + oLT
if arg1 == 0 -> <load-ops> arg + oLTZ
<push-op> arg1 + <load-ops> arg2 + oGTE
if arg1 == 0 -> <load-ops> arg + oGTEZ
<push-op> arg1 + <load-ops> arg2 + oGT
if arg1 == 0 -> <load-ops> arg + oGTZ
<push-op> arg1 + <load-ops> arg2 + oLTE
if arg1 == 0 -> <load-ops> arg + oLTEZ
STEP 2a:
if the <push-op> op is still there
<push-op> arg
if arg < 256 -> oPUSHB arg
else -> oPUSH arg
STEP 3
oNEG + oADD -> oSUB
oNEG + oSUB -> oADD
pjopt.c: BranchOptimize
oNOT + oJEQUZ -> oJNEQZ
oNOT + oJNEQZ -> oJEQUZ
oNEG + oJLTZ -> oJGTZ
oNEG + oJGTEZ -> oJLTEZ
oNEG + oJGTZ -> oJLTZ
oNEG + oJLTEZ -> oJGTEZ
oEQU + oNOT -> oNEQ
oEQU + oJEQUZ -> oJNEQ
oEQU + oJNEQZ -> oJEQU
oNEQ + oNOT -> oEQU
oNEQ + oJEQUZ -> oJEQU
oNEQ + oJNEQZ -> oJNEQ
oLT + oNOT -> oGTE
oLT + oJEQUZ -> oJGTE
oLT + oJNEQZ -> oJLT
oGTE + oNOT -> oLT
oGTE + oJEQUZ -> oJLT
oGTE + oJNEQZ -> oJGTE
oGT + oNOT -> oLTE
oGT + oJEQUZ -> oJLTE
oGT + oJNEQZ -> oJGT
oLTE + oJNOT -> oGT
oLTE + oJEQUZ -> oJGT
oLTE + oJNEQZ -> oJLTE
oEQUZ + oNOT -> oNEQZ
oEQUZ + oJEQUZ -> oJNEQZ
oEQUZ + oJNEQZ -> oJEQUZ
oNEQZ + oNOT -> oEQUZ
oNEQZ + oJEQUZ -> oJEQUZ
oNEQZ + oJNEQZ -> oJNEQZ
oLTZ + oNOT -> oGTEZ
oLTZ + oJEQUZ -> oJGTEZ
oLTZ + oJNEQZ -> oJLTZ
oGTEZ + oNOT -> oLTZ
oGTEZ + oJEQUZ -> oJLTZ
oGTEZ + oJNEQZ -> oJGTEZ
oGTZ + oNOT -> oLTEZ
oGTZ + oJEQUZ -> oJLTEZ
oGTZ + oJNEQZ -> oJGTZ
oLTEZ + oNOT -> oGTZ
oLTEZ + oJEQUZ -> oJGTZ
oLTEZ + oJNEQZ -> oJLTEZ
plopt.c:LoadOptimize()
Eliminate duplicate loads
oLOD arg1 + oLOAD arg1 -> oLOD arg1 + oDUP
Convert loads indexed by a constant to unindexed loads
!!! DISABLED !!! Does not work because arg2 is a label, not an address !!!
<push-op> arg1 + oLODX arg2 -> oLOD arg1 + arg2
<push-op> arg1 + oLADRX arg2 -> oLADR arg1 + arg2
<push-op> arg1 + oLODBX arg2 -> oLODB arg1 + arg2
<push-op> arg1 + oLODMX arg2 -> oLODM arg1 + arg2
<push-op> arg
if arg < 256 -> oPUSHB arg
plopt.c:StoreOptimize()
Eliminate store followed by load
oSTO arg + oLOAD arg -> oSTO arg + oDUP
Convert stores indexed by a constant to unindexed stores
<push-op> arg1 + ? + oSTOX arg2 -> ? + oSTO arg1 + arg2
<push-op> arg1 + ? + oSTOBX arg2 -> ? + oSTOB arg1 + arg2
Missing local optimization:
Need to check for branches (conditional or unconditional) to the
next instruction.
+208
View File
@@ -0,0 +1,208 @@
====================================================================
000-099: Basic functionality
====================================================================
TEST FILE: 001-beginend.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 002-writeln.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 003-for.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 004-repeat.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 005-while.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 006-optconst.pas
Compiles without error
Executes without error
Output...
You have to use plist to examine the output. All integer constant
expressions are correctly optimized EXCEPT the last one. This
is most like a problem with the way the optimizer buffers instructions
-- i.e., the window is not big enough to capture the full context
Still need to add logic to verify real expressions.
====================================================================
100-199: Math and runtime libraries
====================================================================
TEST FILE: 101-cosine.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 102-cen2fahr.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 103-sumharm.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 104-primes.pas
Fatal Error 43 -- Compilation aborted
0:0013 sieve, primes : array[0..w] of set of 0..maxbit;
Line 0:0012 Error 2e Token 0a
TEST FILE: 105-inflation.pas
Compiles without error
Executes without error
Output is correct
====================================================================
200-299: Strings
====================================================================
TEST FILE: 201-strcat.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 202-strcmp.pas
Compiles without error
Executes without error
Output is correct
====================================================================
500-599: multi-file features: uses, units
====================================================================
TEST FILE: 501-uses.pas
Compiles without error
Gets the following runtime errors:
FILE 0, "src/uses.pas"
PRGM 0, "MYPROGRAM"
FILE 1, "src/unit.pas"
IMPRT 66, L0001, "MYCOSINE"
...
Entry is label L0002
P-Code label L0002 loaded at iSpace[3]
Entry point set to 0x0003
Last p-code address: 0x0063
ERROR: Could not find code label 0x00000001
ERROR: Failed to bind program addresses
ERROR: Could not load src/uses.PCD
TEST FILE: 501-unit.pas
Compiles without error
Executes with error as exepected:
ERROR: Cannot execute. Entry Point NOT found
Runtime error 0x80 -- Execution Stopped
OK!
Line 0:0016 Error 36 Token 01 (READKEY)
====================================================================
800-899: Erie pascal programs
====================================================================
TEST FILE: 801-cgihello.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 802-cgiinfo.pas
Compiles without error
Executes without error
Output is correct
TEST FILE: 803-redirect.pas
Fatal Error 14 -- Compilation aborted
0:0031 len : 0..maxint;
0:0039 val(ContentLength, len, err)
Line 0:0039 Error 42 Token 51
Error 42: eVARPARMTYPE
Token 51: tSUBRANGE
len is used as output in VAR built-in. Compiler currently won't
accept subrange of type for type. It should as an input, but it
should not as an output unless there is range checking.
0:0061 EncodedVariable, DecodedVariable, name, value : string;
0:0063 procedure ProcessNameValuePair(var name, value : string);
Line 0:0063 Error 0e Token 4b
Error 0e: eINDENT
Token 4b: sSTRING
Declared from line 'if (token != tIDENT) error (eIDENT);'
in function declare parameter. tkn_strt = 'NAME'
Problem with scope of names. 'name' already exists in outscope and
cannot be redeclared in the innerscope.
TEST FILE: 804-cgiform.pas
Fatal Error 29 -- Compilation aborted
Uses 'list of'
0:0054 NameValuePairs : list of NameValuePair;
Line 0:0054 Error 1e Token 01 (LIST)
TEST FILE: 805-cgimail.pas
Fatal Error 29 -- Compilation aborted
Uses type file name
strErrorLink, strSuccessLink : filename;
Line 0:0018 Error 1e Token 01 (FILENAME)
filename is an Irie pascal type.
Also uses Irie pascal specific file IO calls.
TEST FILE: 806-cgicook.pas
Fatal Error 29 -- Compilation aborted
Uses 'list of'
0:0088 CookieList = list of Cookie;
Line 0:0088 Error 1e Token 01 (LIST)
====================================================================
900-999: Misc. large programs not targeted at any particular feature.
====================================================================
TEST FILE: 901-pageutils.pas
Fatal Error 45 -- Compilation aborted
Reirects standard input and output:
CONST
...
input = 1;
output = 2;
Line 0:0654 Error 0f Token 45
0f = eIMPLEMENTATION
45 = sFILE
Issues the list_cb_type
0:4640 PROCEDURE init_list (VAR list: list_cb_type; max_nol: short) ;
Line 0:4640 Error 2c Token 01 (LIST_CB_TYPE)
+52
View File
@@ -0,0 +1,52 @@
/***************************************************************************
* pdbg.h
* External Declarations associated with the P-Code debugger
*
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 __PDBG_H
#define __PDBG_H
/***************************************************************************
* Included Files
***************************************************************************/
#include "pexec.h"
/***************************************************************************
* Global Function Prototypes
***************************************************************************/
extern void dbg_run(struct pexec_s *st);
#endif /* __PDBG_H */
+156
View File
@@ -0,0 +1,156 @@
/****************************************************************************
* pexec.h
*
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 __PEXEC_H
#define __PEXEC_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Definitions
****************************************************************************/
#define BPERI 2
#define ITOBSTACK(i) ((i) << 1)
#define BTOISTACK(i) ((i) >> 1)
#define ROUNDBTOI(i) (((i) + 1) >> 1)
/****************************************************************************
* Type Definitions
****************************************************************************/
typedef uint16_t ustack_t; /* Stack values are 16-bits in length */
typedef int16_t sstack_t;
typedef uint16_t paddr_t; /* Addresses are 16-bits in length */
typedef uint16_t level_t; /* Limits to MAXUINT16 levels */
union stack_u
{
ustack_t *i;
uint8_t *b;
};
typedef union stack_u stackType;
/* This structure describes the parameters needed to initialize the p-code
* interpreter.
*/
struct pexec_attr_s
{
/* Instruction space (I-Space) */
FAR uint8_t *ispace; /* Allocated I-Space containing p-code data */
paddr_t entry; /* Entry point */
paddr_t maxpc; /* Last valid p-code address */
/* Read-only data block */
FAR uint8_t *rodata; /* Address of read-only data block */
paddr_t rosize; /* Size of read-only data block */
/* Allocate for variable storage */
paddr_t varsize; /* Variable storage size */
paddr_t strsize; /* String storage size */
};
/* This structure defines the current state of the p-code interpreter */
struct pexec_s
{
/* This is the emulated P-Machine stack (D-Space) */
stackType dstack;
/* This is the emulated P-Machine instruction space (I-Space) */
FAR uint8_t *ispace;
/* Address of last valid P-Code */
paddr_t maxpc;
/* These are the emulated P-Machine registers:
*
* spb: Base of the stack
* sp: The Pascal stack pointer
* csp: The current top of the stack used to manage string
* storage
* fp: Base Register of the current stack frame. Holds the address
* of the base of the stack frame of the current block.
* fop: Pointer to section containing read-only data
* pc: Holds the current p-code location
*/
paddr_t spb; /* Pascal stack base */
paddr_t sp; /* Pascal stack pointer */
paddr_t csp; /* Character stack pointer */
paddr_t fp; /* Base of the current frame */
paddr_t rop; /* Read-only data pointer */
paddr_t pc; /* Program counter */
/* Info needed to perform a simulated reset */
paddr_t strsize; /* String stack size */
paddr_t rosize; /* Read-only stack size */
paddr_t entry; /* Entry point */
paddr_t stacksize; /* (debug only) */
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif
EXTERN FAR struct pexec_s *pload(const char *filename, paddr_t varsize, paddr_t strsize);
EXTERN FAR struct pexec_s *pexec_init(struct pexec_attr_s *attr);
EXTERN int pexec(FAR struct pexec_s *st);
EXTERN void pexec_reset(struct pexec_s *st);
EXTERN void pexec_release(struct pexec_s *st);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __PEXEC_H */
+408
View File
@@ -0,0 +1,408 @@
/****************************************************************************
* pinsn16.h
* 16-bit P-code operation code definitions
*
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 __PINSN16_H
#define __PINSN16_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Definitions
****************************************************************************/
/* Op-code bit definitions */
#define o16 (0x80)
#define o8 (0x40)
/* Opcode Encoding Summary:
*
* NO ARGS arg8 ONLY arg16 ONLY BOTH
* 00xx xxxx 01xx xxxx 10xx xxxx 11xx xxxx
* xx00 0000 NOP --- --- ---
* xx00 0001 NEG --- --- ---
* xx00 0010 ABS --- --- ---
* xx00 0011 INC --- --- ---
* xx00 0100 DEC --- --- ---
* xx00 0101 NOT --- --- ---
* xx00 0110 ADD --- --- ---
* xx00 0111 SUB --- --- ---
* xx00 1000 MUL --- --- PCAL l,ilbl
* xx00 1001 DIV --- --- ---
* xx00 1010 MOD --- --- ---
* xx00 1011 SLL --- --- ---
* xx00 1100 SRL --- --- ---
* xx00 1101 SRA --- --- ---
* xx00 1110 OR --- --- ---
* xx00 1111 AND --- --- ---
*
* xx01 0000 EQUZ --- JEQUZ ilbl ---
* xx01 0001 NEQZ --- JNEQZ ilbl ---
* xx01 0010 LTZ --- JLTZ ilbl ---
* xx01 0011 GTEZ --- JGTEZ ilbl ---
* xx01 0100 GTZ --- JGTZ ilbl ---
* xx01 0101 LTEZ --- JLTEZ ilbl ---
* xx01 0110 --- --- JMP ilbl ---
* xx01 0111 --- --- --- ---
* xx01 1000 EQU --- JEQU ilbl ---
* xx01 1001 NEQ --- JNEQ ilbl ---
* xx01 1010 LT --- JLT ilbl ---
* xx01 1011 GTE --- JGTE ilbl ---
* xx01 1100 GT --- JGT ilbl ---
* xx01 1101 LTE --- JLTE ilbl ---
* xx01 1110 --- --- --- ---
* xx01 1111 BIT --- --- ---
*
* xx10 0000 LDI --- LD uoffs LDS lvl,offs
* xx10 0001 LDIH --- LDH uoffs LDSH lvl,offs
* xx10 0010 LDIB --- LDB uoffs LDSB lvl,offs
* xx10 0011 LDIM --- LDM uoffs LDSM lvl,offs
* xx10 0100 STI --- ST uoffs STS lvl,offs
* xx10 0101 STIH --- STH uoffs STSH lvl,offs
* xx10 0110 STIB --- STB uoffs STSB lvl,offs
* xx10 0111 STIM --- STM uoffs STSM lvl,offs
* xx10 1000 DUP --- LDX uoffs LDSX lvl,offs
* xx10 1001 DUPH --- LDXH uoffs LDSXH lvl,offs
* xx10 1010 PUSHS --- LDXB uoffs LDSXB lvl,offs
* xx10 1011 POPS --- LDXM uoffs LDSXM lvl,offs
* xx10 1100 --- --- STX uoffs STSX lvl,offs
* xx10 1101 --- --- STXH uoffs STSXH lvl,offs
* xx10 1110 --- --- STXB uoffs STSXB lvl,offs
* xx10 1111 RET --- STXM uoffs STSXM lvl,offs
*
* xx11 0000 --- FLOAT fop LA uoffs LAS lvl,offs
* xx11 0001 --- --- LAC dlbl ---
* xx11 0010 --- --- --- ---
* xx11 0011 --- --- --- ---
* xx11 0100 --- PUSHB n PUSH nn ---
* xx11 0101 --- --- INDS nn ---
* xx11 0110 --- --- --- ---
* xx11 0111 --- --- --- ---
* xx11 1000 --- --- LAX uoffs LASX lvl,offs
* xx11 1001 --- --- LIB lop SYSIO fn,sop
* xx11 1010 --- --- --- ---
* xx11 1011 --- --- --- ---
* xx11 1100 --- --- --- ---
* xx11 1101 --- --- --- ---
* xx11 1110 --- --- --- ---
* xx11 1111 END --- *LABEL ilbl *LINE fn,lineno
*
* KEY:
* n = 8-bit value (unsigned)
* lvl = 8-bit static nesting level offset (unsigned)
* vt = 8-bit type code (unsigned)
* nn = 16-bit value (signed)
* fop = 8-bit floating point operation
* sop = 16-bit sysio operation
* lop = 16-bit library call identifier
* fn = 8-bit file number
* ilbl = instruction space label
* dlbl = stack data label
* offs = 16-bit frame offset (signed)
* uoffs = 16-bit base offset (unsigned)
* c = string follows pseudo-operation
* * = Indicates pseudo-operations (these are removed
* after final fixup of the object file).
*/
/** OPCODES WITH NO ARGUMENTS ***********************************************/
/* Program control (No stack arguments) */
#define oNOP (0x00)
/* Arithmetic & logical & and integer conversions (One 16-bit stack argument) */
#define oNEG (0x01)
#define oABS (0x02)
#define oINC (0x03)
#define oDEC (0x04)
#define oNOT (0x05)
/* Arithmetic & logical (Two 16-bit stack arguments) */
#define oADD (0x06)
#define oSUB (0x07)
#define oMUL (0x08)
#define oDIV (0x09)
#define oMOD (0x0a)
#define oSLL (0x0b)
#define oSRL (0x0c)
#define oSRA (0x0d)
#define oOR (0x0e)
#define oAND (0x0f)
/* Comparisons (One 16-bit stack argument) */
#define oEQUZ (0x10)
#define oNEQZ (0x11)
#define oLTZ (0x12)
#define oGTEZ (0x13)
#define oGTZ (0x14)
#define oLTEZ (0x15)
/* 0x16-0x17 -- unassigned */
/* Comparisons (Two 16-bit stack arguments) */
#define oEQU (0x18)
#define oNEQ (0x19)
#define oLT (0x1a)
#define oGTE (0x1b)
#define oGT (0x1c)
#define oLTE (0x1d)
/* 0x1e -- unassigned */
#define oBIT (0x1f)
/* Load Immediate */
#define oLDI (0x20) /* (One 16-bit stack argument) */
#define oLDIH (0x21) /* (One 16-bit stack argument) */
#define oLDIB (0x22) /* (One 16-bit stack argument) */
#define oLDIM (0x23) /* (Two 16-bit stack arguments) */
/* Store Immediate */
#define oSTI (0x24) /* (One 32-bit and one 16-bit stack arguments) */
#define oSTIH (0x25) /* (Two 16-bit stack arguments) */
#define oSTIB (0x26) /* (Two 16-bit stack arguments) */
#define oSTIM (0x27) /* (Two + n 16-bit stack arguments) */
/* Data stack */
#define oDUP (0x28) /* (One 32-bit stack argument */
#define oDUPH (0x29) /* (One 16-bit stack argument) */
/* 0x2a - 0x2b -- unassigned */
#define oPUSHS (0x2a) /* No arguments */
#define oPOPS (0x2b) /* (One 16-bit stack argument) */
/* 0x2c - 0x2e -- unassigned */
/* Program control (No stack arguments)
* Behavior:
* Pop return address
* Pop saved base register (BR)
* Discard saved base address
* Set program counter (PC) to return address
*/
#define oRET (0x2f)
/* 0x30 - 0x3e -- unassigned */
/* System Functions (No stack arguments) */
#define oEND (0x3f)
/** OPCODES WITH SINGLE BYTE ARGUMENT (arg8) ********************************/
/* (o8|0x00)-(o8|0x2f) -- unassigned */
/* Floating point operations: arg8 = FP op-code */
#define oFLOAT (o8|0x30)
/* (o8|0x31)-(o8|0x33) -- unassigned */
/* Data stack: arg8 = 8 bit unsigned data (no stack arguments) */
#define oPUSHB (o8|0x34)
/* (o8|0x35)-(o8|0x3f) -- unassigned */
/** OPCODES WITH SINGLE 16-BIT ARGUMENT (arg16) *****************************/
/* (o16|0x00)-(o16|0x0f) -- unassigned */
/* Program control: arg16 = unsigned label (One 16-bit stack argument) */
#define oJEQUZ (o16|0x10)
#define oJNEQZ (o16|0x11)
#define oJLTZ (o16|0x12)
#define oJGTEZ (o16|0x13)
#define oJGTZ (o16|0x14)
#define oJLTEZ (o16|0x15)
/* Program control: arg16 = unsigned label (no stack arguments) */
#define oJMP (o16|0x16)
/* (o16|0x17) -- unassigned */
/* Program control: arg16 = unsigned label (One 16-bit stack argument) */
#define oJEQU (o16|0x18)
#define oJNEQ (o16|0x19)
#define oJLT (o16|0x1a)
#define oJGTE (o16|0x1b)
#define oJGT (o16|0x1c)
#define oJLTE (o16|0x1d)
/* (o16|0x1e)-(o16|0x1f) -- unassigned */
/* Load: arg16 = unsigned base offset */
#define oLD (o16|0x20) /* (no stack arguments) */
#define oLDH (o16|0x21) /* (no stack arguments) */
#define oLDB (o16|0x22) /* (no stack arguments) */
#define oLDM (o16|0x23) /* (One 16-bit stack argument) */
/* Store: arg16 = unsigned base offset */
#define oST (o16|0x24) /* (One 32-bit stack argument) */
#define oSTH (o16|0x25) /* (One 16-bit stack argument) */
#define oSTB (o16|0x26) /* (One 16-bit stack argument) */
#define oSTM (o16|0x27) /* (One+n 16-bit stack arguments) */
/* Load Indexed: arg16 = unsigned base offset */
#define oLDX (o16|0x28) /* (One 16-bit stack argument) */
#define oLDXH (o16|0x29) /* (One 16-bit stack argument) */
#define oLDXB (o16|0x2a) /* (One 16-bit stack argument) */
#define oLDXM (o16|0x2b) /* (Two 16-bit stack arguments) */
/* Store Indexed: arg16 = unsigned base offset */
#define oSTX (o16|0x2c) /* (One 32-bit + one 16-bit stack arguments) */
#define oSTXH (o16|0x2d) /* (Two 16-bit stack arguments) */
#define oSTXB (o16|0x2e) /* (Two 16-bit stack arguments) */
#define oSTXM (o16|0x2f) /* (Two+n 16-bit stack arguments) */
/* Load address relative to stack base: arg16 = unsigned offset */
#define oLA (o16|0x30)
/* Load absolute stack address: arg16 = RODATA offset (No stack arguments) */
#define oLAC (o16|0x31)
/* (o16|0x32)-(o16|0x33) -- unassigned */
/* Data stack: arg16 = 16 bit signed data (no stack arguments) */
#define oPUSH (o16|0x34)
#define oINDS (o16|0x35)
/* (o16|0x34)-(o16|0x37) -- unassigned */
/* Load address relative to stack base: arg16 = unsigned offset, TOS=index */
#define oLAX (o16|0x38)
/* System functions: arg16 = 16-bit library call identifier */
#define oLIB (o16|0x39)
/* (o16|0x3a)-(o16|0x3e) -- unassigned */
/* Program control: arg16 = unsigned label (no stack arguments) */
#define oLABEL (o16|0x3f)
/** OPCODES WITH 24-BITS OF ARGUMENET (arg8 + arg16) ************************/
/* (o16|o8|0x00)-(o8|o16|0x07) -- unassigned */
/* Program Control: arg8 = level; arg16 = unsigned label
* (No stack arguments)
* Behavior:
* Push base address of level
* Push base register (BR) value
* Set new base register value (BR) as top of stack
* Push return address
* Set program counter (PC) for address associated with label
*/
#define oPCAL (o16|o8|0x08)
/* (o16|o8|0x09)-(o8|o16|0x1f) -- unassigned */
/* Load: arg8 = level; arg16 = signed frame offset */
#define oLDS (o16|o8|0x20) /* (no stack arguments) */
#define oLDSH (o16|o8|0x21) /* (no stack arguments) */
#define oLDSB (o16|o8|0x22) /* (no stack arguments) */
#define oLDSM (o16|o8|0x23) /* (One 16-bit stack argument) */
/* Store: arg8 = level; arg16 = signed frame offset */
#define oSTS (o16|o8|0x24) /* (One 32-bit stack argument) */
#define oSTSH (o16|o8|0x25) /* (One 16-bit stack argument) */
#define oSTSB (o16|o8|0x26) /* (One 16-bit stack argument) */
#define oSTSM (o16|o8|0x27) /* (One+n 16-bit stack arguments) */
/* Load Indexed: arg8 = level; arg16 = signed frame offset */
#define oLDSX (o16|o8|0x28) /* (One 16-bit stack argument) */
#define oLDSXH (o16|o8|0x29) /* (One 16-bit stack argument) */
#define oLDSXB (o16|o8|0x2a) /* (One 16-bit stack argument) */
#define oLDSXM (o16|o8|0x2b) /* (Two 16-bit stack arguments) */
/* Store Indexed: arg8 = level; arg16 = signed frame offset */
#define oSTSX (o16|o8|0x2c) /* (One 32-bit + one 16-bit stack arguments) */
#define oSTSXH (o16|o8|0x2d) /* (Two 16-bit stack arguments) */
#define oSTSXB (o16|o8|0x2e) /* (Two 16-bit stack arguments) */
#define oSTSXM (o16|o8|0x2f) /* (Two+n 16-bit stack arguments) */
/* FOR LAS/LASX arg8 = level; arg16 = signed frame offset
* (no stack arguments)
*/
#define oLAS (o16|o8|0x30)
#define oLASX (o16|o8|0x38)
/* System calls:
* For SYSIO: arg8 = file number; arg16 = sub-function code
*/
#define oSYSIO (o16|o8|0x39)
/* (o16|o8|0x3a)-(o8|o16|0x3e) -- unassigned */
/* Pseudo-operations:
* For LINE: arg8 = file number; arg16 = line number
*/
#define oLINE (o16|o8|0x3f)
#endif /* __PINSN16_H */
+76
View File
@@ -0,0 +1,76 @@
############################################################################
# insn16/libinsn/Makefile
#
# Copyright (C) 2008 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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
#
LIBINSNDIR = ${shell pwd}
INSNDIR = $(LIBINSNDIR)/..
PASCAL = $(LIBINSNDIR)/../..
include $(PASCAL)/Make.config
include $(PASCAL)/Make.defs
INCDIR = $(PASCAL)/include
LIBDIR = $(PASCAL)/lib
#
# Tools
#
EXTRA_INCLUDES = -I$(INSNDIR)/include
INCLUDES += $(EXTRA_INCLUDES)
CFLAGS += $(EXTRA_INCLUDES)
#
# Objects and targets
#
LIBINSNSRCS = paddopcode.c paddtmpopcode.c pdasm.c pgen.c \
pgetopcode.c preloc.c
LIBINSNOBJS = $(LIBINSNSRCS:.c=.o)
OBJS = $(LIBINSNOBJS)
all: libinsn.a
.PHONY: all libinsn.a clean
$(OBJS): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(LIBDIR)/libinsn.a: $(LIBINSNOBJS)
$(AR) $(ARFLAGS) $@ $^
libinsn.a: $(LIBDIR)/libinsn.a
clean:
$(RM) libinsn.a *.o core *~
+100
View File
@@ -0,0 +1,100 @@
/**********************************************************************
* paddopcode
* P-Code access utilities
*
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 "keywords.h"
#include "podefs.h"
#include "pinsn16.h"
#include "paslib.h"
#include "pofflib.h"
#include "pinsn.h"
/**********************************************************************
* Private Function Prototypes
**********************************************************************/
/**********************************************************************
* Global Variables
**********************************************************************/
/**********************************************************************
* Private Variables
**********************************************************************/
/**********************************************************************
* Private Functions
**********************************************************************/
/**********************************************************************
* Global Functions
**********************************************************************/
/**********************************************************************/
void insn_AddOpCode(poffHandle_t handle, OPTYPE *ptr)
{
/* Write the opcode which is always present */
(void)poffAddProgByte(handle, ptr->op);
/* Write the 8-bit argument if present */
if (ptr->op & o8)
{
(void)poffAddProgByte(handle, ptr->arg1);
}
/* Write the 16-bit argument if present */
if (ptr->op & o16)
{
(void)poffAddProgByte(handle, (ptr->arg2 >> 8));
(void)poffAddProgByte(handle, (ptr->arg2 & 0xff));
}
}
/**********************************************************************/
void insn_ResetOpCodeWrite(poffHandle_t handle)
{
poffResetAccess(handle);
}
/***********************************************************************/
+100
View File
@@ -0,0 +1,100 @@
/**********************************************************************
* paddtmpopcode
* P-Code access utilities
*
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 "keywords.h"
#include "podefs.h"
#include "pinsn16.h"
#include "paslib.h"
#include "pofflib.h"
#include "pinsn.h"
/**********************************************************************
* Private Function Prototypes
**********************************************************************/
/**********************************************************************
* Global Variables
**********************************************************************/
/**********************************************************************
* Private Variables
**********************************************************************/
/**********************************************************************
* Private Functions
**********************************************************************/
/**********************************************************************
* Global Functions
**********************************************************************/
/**********************************************************************/
void insn_AddTmpOpCode(poffProgHandle_t progHandle, OPTYPE *ptr)
{
/* Write the opcode which is always present */
(void)poffAddTmpProgByte(progHandle, ptr->op);
/* Write the 8-bit argument if present */
if (ptr->op & o8)
{
(void)poffAddTmpProgByte(progHandle, ptr->arg1);
}
/* Write the 16-bit argument if present */
if (ptr->op & o16)
{
(void)poffAddTmpProgByte(progHandle, (ptr->arg2 >> 8));
(void)poffAddTmpProgByte(progHandle, (ptr->arg2 & 0xff));
}
}
/**********************************************************************/
void insn_ResetTmpOpCodeWrite(poffProgHandle_t progHandle)
{
poffResetProgHandle(progHandle);
}
/***********************************************************************/
+569
View File
@@ -0,0 +1,569 @@
/**********************************************************************
* pdasm.c
* P-Code Disassembler
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/***********************************************************************
* Included Files
***********************************************************************/
#include <stdint.h>
#include <stdio.h>
#include "keywords.h"
#include "podefs.h"
#include "pinsn16.h"
#include "pfdefs.h"
#include "pxdefs.h"
#include "paslib.h"
#include "pinsn.h"
/***********************************************************************
* Pre-processor Definitions
***********************************************************************/
/* These are all the format codes that apply to opcodes the an arg16 */
#define NOARG16 0
#define HEX 1
#define DECIMAL 2
#define UDECIMAL 3
#define LABEL_DEC 4
#define xOP 5
#define lbOP 6
#define fpOP 7
#define COMMENT 8
/* The following table defines everything that is needed to disassemble
* a P-Code. NOTE: The order of definition in this table must exactly
* match the declaration sequence in pinsn.h. */
static const char invOp[] = "Invalid Opcode";
static const struct
{
const char *opName; /* Opcode mnemonics */
uint8_t format; /* arg16 format */
} opTable[256] =
{
/******************* OPCODES WITH NO ARGUMENTS ************************/
/* Program control (No stack arguments) */
/* 0x00 */ { "NOP ", NOARG16 },
/* Arithmetic & logical & and integer conversions (One stack argument) */
/* 0x01 */ { "NEG ", NOARG16 },
/* 0x02 */ { "ABS ", NOARG16 },
/* 0x03 */ { "INC ", NOARG16 },
/* 0x04 */ { "DEC ", NOARG16 },
/* 0x05 */ { "NOT ", NOARG16 },
/* Arithmetic & logical (Two stack arguments) */
/* 0x06 */ { "ADD ", NOARG16 },
/* 0x07 */ { "SUB ", NOARG16 },
/* 0x08 */ { "MUL ", NOARG16 },
/* 0x09 */ { "DIV ", NOARG16 },
/* 0x0a */ { "MOD ", NOARG16 },
/* 0x0b */ { "SLL ", NOARG16 },
/* 0x0c */ { "SRL ", NOARG16 },
/* 0x0d */ { "SRA ", NOARG16 },
/* 0x0e */ { "OR ", NOARG16 },
/* 0x0f */ { "AND ", NOARG16 },
/* Comparisons (One stack argument) */
/* 0x10 */ { "EQUZ ", NOARG16 },
/* 0x11 */ { "NEQZ ", NOARG16 },
/* 0x12 */ { "LTZ ", NOARG16 },
/* 0x13 */ { "GTEZ ", NOARG16 },
/* 0x14 */ { "GTZ ", NOARG16 },
/* 0x15 */ { "LTEZ ", NOARG16 },
/* 0x16 */ { invOp, NOARG16 },
/* 0x17 */ { invOp, NOARG16 },
/* Comparisons (Two stack arguments) */
/* 0x18 */ { "EQU ", NOARG16 },
/* 0x19 */ { "NEQ ", NOARG16 },
/* 0x1a */ { "LT ", NOARG16 },
/* 0x1b */ { "GTE ", NOARG16 },
/* 0x1c */ { "GT ", NOARG16 },
/* 0x1d */ { "LTE ", NOARG16 },
/* 0x1e */ { invOp, NOARG16 },
/* 0x1f */ { "BIT ", NOARG16 },
/* Load (One) or Store (Two stack argument) */
/* 0x20 */ { "LDI ", NOARG16 },
/* 0x21 */ { "LDIH", NOARG16 },
/* 0x22 */ { "LDIB", NOARG16 },
/* 0x23 */ { "LDIM", NOARG16 },
/* 0x24 */ { "STI ", NOARG16 },
/* 0x25 */ { "STIH", NOARG16 },
/* 0x26 */ { "STIB", NOARG16 },
/* 0x27 */ { "STIM", NOARG16 },
/* Data stack operations */
/* 0x29 */ { "DUP ", NOARG16 },
/* 0x29 */ { "DUPH ", NOARG16 },
/* 0x2a */ { "PUSHS", NOARG16 },
/* 0x2b */ { "POPS", NOARG16 },
/* 0x2c */ { invOp, NOARG16 },
/* 0x2d */ { invOp, NOARG16 },
/* 0x2e */ { invOp, NOARG16 },
/* 0x2f */ { "RET ", NOARG16 },
/* 0x30 */ { invOp, NOARG16 },
/* 0x31 */ { invOp, NOARG16 },
/* 0x32 */ { invOp, NOARG16 },
/* 0x33 */ { invOp, NOARG16 },
/* 0x34 */ { invOp, NOARG16 },
/* 0x35 */ { invOp, NOARG16 },
/* 0x36 */ { invOp, NOARG16 },
/* 0x37 */ { invOp, NOARG16 },
/* 0x38 */ { invOp, NOARG16 },
/* System Functions (No stack arguments) */
/* 0x39 */ { invOp, NOARG16 },
/* 0x3a */ { invOp, NOARG16 },
/* 0x3b */ { invOp, NOARG16 },
/* 0x3c */ { invOp, NOARG16 },
/* 0x3d */ { invOp, NOARG16 },
/* 0x3e */ { invOp, NOARG16 },
/* 0x3f */ { "EXIT ", NOARG16 },
/************** OPCODES WITH SINGLE BYTE ARGUMENT (arg8) ***************/
/* 0x40 */ { invOp, NOARG16 },
/* 0x41 */ { invOp, NOARG16 },
/* 0x42 */ { invOp, NOARG16 },
/* 0x43 */ { invOp, NOARG16 },
/* 0x44 */ { invOp, NOARG16 },
/* 0x45 */ { invOp, NOARG16 },
/* 0x46 */ { invOp, NOARG16 },
/* 0x47 */ { invOp, NOARG16 },
/* 0x48 */ { invOp, NOARG16 },
/* 0x49 */ { invOp, NOARG16 },
/* 0x4a */ { invOp, NOARG16 },
/* 0x4b */ { invOp, NOARG16 },
/* 0x4c */ { invOp, NOARG16 },
/* 0x4d */ { invOp, NOARG16 },
/* 0x4e */ { invOp, NOARG16 },
/* 0x4f */ { invOp, NOARG16 },
/* 0x50 */ { invOp, NOARG16 },
/* 0x51 */ { invOp, NOARG16 },
/* 0x52 */ { invOp, NOARG16 },
/* 0x53 */ { invOp, NOARG16 },
/* 0x54 */ { invOp, NOARG16 },
/* 0x55 */ { invOp, NOARG16 },
/* 0x56 */ { invOp, NOARG16 },
/* 0x57 */ { invOp, NOARG16 },
/* 0x58 */ { invOp, NOARG16 },
/* 0x59 */ { invOp, NOARG16 },
/* 0x5a */ { invOp, NOARG16 },
/* 0x5b */ { invOp, NOARG16 },
/* 0x5c */ { invOp, NOARG16 },
/* 0x5d */ { invOp, NOARG16 },
/* 0x5e */ { invOp, NOARG16 },
/* 0x5f */ { invOp, NOARG16 },
/* Data stack: arg8 = 8 bit unsigned data (no stack arguments) */
/* 0x60 */ { invOp, NOARG16 },
/* 0x61 */ { invOp, NOARG16 },
/* 0x62 */ { invOp, NOARG16 },
/* 0x63 */ { invOp, NOARG16 },
/* 0x64 */ { invOp, NOARG16 },
/* 0x65 */ { invOp, NOARG16 },
/* 0x66 */ { invOp, NOARG16 },
/* 0x67 */ { invOp, NOARG16 },
/* 0x68 */ { invOp, NOARG16 },
/* 0x69 */ { invOp, NOARG16 },
/* 0x6a */ { invOp, NOARG16 },
/* 0x6b */ { invOp, NOARG16 },
/* 0x6c */ { invOp, NOARG16 },
/* 0x6d */ { invOp, NOARG16 },
/* 0x6e */ { invOp, NOARG16 },
/* 0x6f */ { invOp, NOARG16 },
/* Floating Point Operations: arg8 = FP op-code */
/* 0x70 */ { "FLOAT", fpOP },
/* 0x71 */ { invOp, NOARG16 },
/* 0x72 */ { invOp, NOARG16 },
/* 0x73 */ { invOp, NOARG16 },
/* 0x74 */ { "PUSHB", NOARG16 },
/* 0x75 */ { invOp, NOARG16 },
/* 0x76 */ { invOp, NOARG16 },
/* 0x77 */ { invOp, NOARG16 },
/* 0x78 */ { invOp, NOARG16 },
/* 0x79 */ { invOp, NOARG16 },
/* 0x7a */ { invOp, NOARG16 },
/* 0x7b */ { invOp, NOARG16 },
/* 0x7c */ { invOp, NOARG16 },
/* 0x7d */ { invOp, NOARG16 },
/* 0x7e */ { invOp, NOARG16 },
/* 0x7f */ { invOp, NOARG16 },
/************ OPCODES WITH SINGLE 16-BIT ARGUMENT (arg16) ************/
/* 0x80 */ { invOp, NOARG16 },
/* 0x81 */ { invOp, NOARG16 },
/* 0x82 */ { invOp, NOARG16 },
/* 0x83 */ { invOp, NOARG16 },
/* 0x84 */ { invOp, NOARG16 },
/* 0x85 */ { invOp, NOARG16 },
/* 0x86 */ { invOp, NOARG16 },
/* 0x87 */ { invOp, NOARG16 },
/* 0x88 */ { invOp, NOARG16 },
/* 0x89 */ { invOp, NOARG16 },
/* 0x8a */ { invOp, NOARG16 },
/* 0x8b */ { invOp, NOARG16 },
/* 0x8c */ { invOp, NOARG16 },
/* 0x8d */ { invOp, NOARG16 },
/* 0x8e */ { invOp, NOARG16 },
/* 0x8f */ { invOp, NOARG16 },
/* Program control: arg16 = unsigned label (One stack argument) */
/* 0x90 */ { "JEQUZ", HEX },
/* 0x91 */ { "JNEQZ", HEX },
/* 0x92 */ { "JLTZ ", HEX },
/* 0x93 */ { "JGTEZ", HEX },
/* 0x94 */ { "JGTZ ", HEX },
/* 0x95 */ { "JLTEZ", HEX },
/* Program control: arg16 = unsigned label (no stack arguments) */
/* 0x96 */ { "JMP ", HEX },
/* 0x97 */ { invOp, NOARG16 },
/* Program control: arg16 = unsigned label (One stack argument) */
/* 0x98 */ { "JEQU ", HEX },
/* 0x99 */ { "JNEQ ", HEX },
/* 0x9a */ { "JLT ", HEX },
/* 0x9b */ { "JGTE ", HEX },
/* 0x9c */ { "JGT ", HEX },
/* 0x9d */ { "JLTE ", HEX },
/* 0x9e */ { invOp, NOARG16 },
/* 0x9f */ { invOp, NOARG16 },
/* Data stack: arg16 = 16 bit signed data (no stack arguments) */
/* Load: arg16 = unsigned base offset (no stack arguments) */
/* 0xa0 */ { "LD ", UDECIMAL },
/* 0xa1 */ { "LDH ", UDECIMAL },
/* 0xa2 */ { "LDB ", UDECIMAL },
/* 0xa3 */ { "LDM ", UDECIMAL },
/* Store: arg16 = unsigned base offset (One stack arguments) */
/* 0xa4 */ { "ST ", UDECIMAL },
/* 0xa5 */ { "STH ", UDECIMAL },
/* 0xa6 */ { "STB ", UDECIMAL },
/* 0xa7 */ { "STM ", UDECIMAL },
/* Load Indexed: arg16 = unsigned base offset (One stack arguments) */
/* 0xa8 */ { "LDX ", UDECIMAL },
/* 0xa9 */ { "LDXH ", UDECIMAL },
/* 0xaa */ { "LDXB ", UDECIMAL },
/* 0xab */ { "LDXM ", UDECIMAL },
/* Store Indexed: arg16 = unsigned base offset (Two stack arguments) */
/* 0xac */ { "STX ", UDECIMAL },
/* 0xad */ { "STXH ", UDECIMAL },
/* 0xae */ { "STXB ", UDECIMAL },
/* 0xaf */ { "STXM ", UDECIMAL },
/* 0xb0 */ { "LA ", UDECIMAL },
/* 0xb1 */ { "LAC ", HEX, },
/* 0xb2 */ { invOp, NOARG16 },
/* 0xb3 */ { invOp, NOARG16 },
/* 0xb4 */ { "PUSH ", DECIMAL },
/* 0xb5 */ { "INDS ", DECIMAL },
/* 0xb6 */ { invOp, NOARG16 },
/* 0xb7 */ { invOp, NOARG16 },
/* 0xb8 */ { "LAX ", UDECIMAL },
/* System operations: arg16 = 16-bit library function identifer */
/* 0xb9 */ { "LIB ", lbOP, },
/* 0xba */ { invOp, NOARG16 },
/* 0xbb */ { invOp, NOARG16 },
/* 0xbc */ { invOp, NOARG16 },
/* 0xbd */ { invOp, NOARG16 },
/* 0xbe */ { invOp, NOARG16 },
/* Program control: arg16 = unsigned label (no stack arguments) */
/* 0xbf */ { "LABEL", LABEL_DEC },
/**** OPCODES WITH BYTE ARGUMENT (arg8) AND 16-BIT ARGUMENT (arg16) ****/
/* 0xc0 */ { invOp, NOARG16 },
/* 0xc1 */ { invOp, NOARG16 },
/* 0xc2 */ { invOp, NOARG16 },
/* 0xc3 */ { invOp, NOARG16 },
/* 0xc4 */ { invOp, NOARG16 },
/* 0xc5 */ { invOp, NOARG16 },
/* 0xc6 */ { invOp, NOARG16 },
/* 0xc7 */ { invOp, NOARG16 },
/* Program Control: arg8 = level; arg16 = unsigned label (No stack
* arguments */
/* 0xc8 */ { "PCAL ", HEX },
/* 0xc9 */ { invOp, NOARG16 },
/* 0xca */ { invOp, NOARG16 },
/* 0xcb */ { invOp, NOARG16 },
/* 0xcc */ { invOp, NOARG16 },
/* 0xcd */ { invOp, NOARG16 },
/* 0xce */ { invOp, NOARG16 },
/* 0xcf */ { invOp, NOARG16 },
/* 0xd0 */ { invOp, NOARG16 },
/* 0xd1 */ { invOp, NOARG16 },
/* 0xd2 */ { invOp, NOARG16 },
/* 0xd3 */ { invOp, NOARG16 },
/* 0xd4 */ { invOp, NOARG16 },
/* 0xd5 */ { invOp, NOARG16 },
/* 0xd6 */ { invOp, NOARG16 },
/* 0xd7 */ { invOp, NOARG16 },
/* 0xd8 */ { invOp, NOARG16 },
/* 0xd9 */ { invOp, NOARG16 },
/* 0xda */ { invOp, NOARG16 },
/* 0xdb */ { invOp, NOARG16 },
/* 0xdc */ { invOp, NOARG16 },
/* 0xdd */ { invOp, NOARG16 },
/* 0xde */ { invOp, NOARG16 },
/* 0xdf */ { invOp, NOARG16 },
/* Load: arg8 = level; arg16 = signed frame offset (no stack arguments) */
/* 0xe0 */ { "LDS ", DECIMAL },
/* 0xe1 */ { "LDSH ", DECIMAL },
/* 0xe2 */ { "LDSB ", DECIMAL },
/* 0xe3 */ { "LDSM ", DECIMAL },
/* Store: arg8 = level; arg16 = signed frame offset (One stack arguments) */
/* 0xe4 */ { "STS ", DECIMAL },
/* 0xe5 */ { "STSH ", DECIMAL },
/* 0xe6 */ { "STSB ", DECIMAL },
/* 0xe7 */ { "STSM ", DECIMAL },
/* Load Indexed: arg8 = level; arg16 = signed frame offset (One stack arguments) */
/* 0xe8 */ { "LDSX ", DECIMAL },
/* 0xe9 */ { "LDSXH", DECIMAL },
/* 0xea */ { "LDSXB", DECIMAL },
/* 0xeb */ { "LDSXM", DECIMAL },
/* Store Indexed: arg8 = level; arg16 = signed frame offset (Two stack arguments) */
/* 0xec */ { "STSX ", DECIMAL },
/* 0xed */ { "STSXH", DECIMAL },
/* 0xee */ { "STSXB", DECIMAL },
/* 0xef */ { "STSXM", DECIMAL },
/* Load Address: arg8 = level; arg16 = signed frame offset (no stack arguments) */
/* 0xf0 */ { "LAS ", DECIMAL },
/* 0xf1 */ { invOp, NOARG16 },
/* 0xf2 */ { invOp, NOARG16 },
/* 0xf3 */ { invOp, NOARG16 },
/* 0xf4 */ { invOp, NOARG16 },
/* 0xf5 */ { invOp, NOARG16 },
/* 0xf6 */ { invOp, NOARG16 },
/* 0xf7 */ { invOp, NOARG16 },
/* 0xf8 */ { "LASX ", DECIMAL },
/* System Functions: (No stack arguments)
* For SYSIO: arg8 = file number; arg16 = sub-function code
*/
/* 0xf9 */ { "SYSIO", xOP, },
/* 0xfa */ { invOp, NOARG16 },
/* 0xfb */ { invOp, NOARG16 },
/* 0xfc */ { invOp, NOARG16 },
/* 0xfd */ { invOp, NOARG16 },
/* 0xfe */ { invOp, NOARG16 },
/* Pseudo-operations:
* For LINE: arg8 = file number; arg16 = line number
*/
/* 0xff */ { "LINE ", COMMENT },
};
static const char invXOp[] = "Invalid SYSIO";
static const char *xName[MAX_XOP] = { /* SYSIO opcode mnemonics */
/* 0x00 */ invXOp, "EOF", "EOLN", "RESET",
/* 0x04 */ "REWRITE", invXOp, invXOp, invXOp,
/* 0x08 */ invXOp, invXOp, invXOp, invXOp,
/* 0x0c */ invXOp, invXOp, invXOp, invXOp,
/* 0x10 */ "READLN", "READPG", "READBIN", "READINT",
/* 0x14 */ "READCHR", "READSTR", "READRL", invXOp,
/* 0x18 */ invXOp, invXOp, invXOp, invXOp,
/* 0x1c */ invXOp, invXOp, invXOp, invXOp,
/* 0x20 */ "WRITELN", "WRITEPG", "WRITEBIN", "WRITEINT",
/* 0x24 */ "WRITECHR", "WRITESTR", "WRITERL" };
static const char invLbOp[] = "Invalid runtime code";
static const char *lbName[MAX_LBOP] = { /* LIB opcode mnemonics */
/* 0x00 */ "GETENV", "STR2STR", "CSTR2STR", "STR2RSTR",
/* 0x04 */ "CSTR2RSTR", "VAL", "MKSTK", "MKSTKSTR",
/* 0x08 */ "MKSTKC", "STRCAT", "STRCATC", "STRCMP" };
static const char invFpOp[] = "Invalid FP Operation";
static const char *fpName[MAX_FOP] = {
/* 0x00 */ invFpOp, "FLOAT", "TRUNC", "ROUND",
/* 0x04 */ "ADD", "SUB", "MUL", "DIV",
/* 0x08 */ "MOD", invFpOp, "EQU", "NEQ",
/* 0x0c */ "LT", "GTE", "GT", "LTE",
/* 0x10 */ "NEG", "ABS", "SQR", "SQRT",
/* 0x14 */ "SIN", "COS", "ATAN", "LN",
/* 0x18 */ "EXP" };
/***********************************************************************/
void insn_DisassemblePCode(FILE* lfile, OPTYPE *pop)
{
/* Indent, comment or label */
switch (opTable[pop->op].format)
{
case LABEL_DEC :
fprintf(lfile, "L%04x: ", pop->arg2);
break;
case COMMENT :
fprintf(lfile, "; ");
break;
default :
fprintf(lfile, " ");
} /* end switch */
/* Special Case Comment line format */
if (opTable[pop->op].format == COMMENT)
{
fprintf(lfile, "%s ", opTable[pop->op].opName);
if (pop->op & o8)
{
fprintf(lfile, "%d", pop->arg1);
if (pop->op & o16)
fprintf(lfile, ":%d", pop->arg2);
} /* end if */
else if (pop->op & o16)
fprintf(lfile, "%d", pop->arg2);
} /* end if */
/* Print normal opCode mnemonic */
else
{
fprintf(lfile, "%s ", opTable[pop->op].opName);
/* Print pop->arg1 (if present) */
if (pop->op & o8) fprintf(lfile, "%d", pop->arg1);
/* Print ar16 (if present) */
if (pop->op & o16)
{
switch (opTable[pop->op].format)
{
case HEX :
if (pop->op & o8) fprintf(lfile, ", ");
fprintf(lfile, "0x%04x", pop->arg2);
break;
case COMMENT :
case DECIMAL :
if (pop->op & o8) fprintf(lfile, ", ");
fprintf(lfile, "%ld", signExtend16(pop->arg2));
break;
case UDECIMAL :
if (pop->op & o8) fprintf(lfile, ", ");
fprintf(lfile, "%u", pop->arg2);
break;
case fpOP :
if ((pop->arg1 & fpMASK) < MAX_FOP)
fprintf(lfile, " %s", fpName[(pop->arg1 & 0x3f)]);
else
fprintf(lfile, " %s", invFpOp);
break;
case xOP :
if (pop->arg2 < MAX_XOP)
fprintf(lfile, ", %s", xName[pop->arg2]);
else
fprintf(lfile, ", %s", invXOp);
break;
case lbOP :
if (pop->arg2 < MAX_LBOP)
fprintf(lfile, "%s", lbName[pop->arg2]);
else
fprintf(lfile, "%s", invLbOp);
break;
case LABEL_DEC :
default :
break;
} /* end switch */
} /* end if */
} /* end else */
/* Don't forget the newline! */
fputc('\n', lfile);
} /* end dissassemblePcode */
/***********************************************************************/
+312
View File
@@ -0,0 +1,312 @@
/**********************************************************************
* pgen.c
* P-Code generation logic
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "config.h" /* Configuration */
#include "keywords.h" /* Standard types */
#include "pdefs.h" /* Common types */
#include "pofflib.h" /* POFF library definitions */
#include "podefs.h" /* Logical opcode definitions */
#include "pedefs.h" /* Error codes */
#include "pinsn16.h" /* 16-bit target INSN opcode definitions */
#include "perr.h" /* Error handling logic */
#include "pinsn.h" /* (to verify prototypes in this file) */
/**********************************************************************
* Definitions
**********************************************************************/
/**********************************************************************
* Global Variables
**********************************************************************/
extern poffHandle_t poffHandle; /* Handle to POFF object */
extern FILE *lstFile; /* LIST file pointer */
extern int16_t level; /* Static nesting level */
/**********************************************************************
* Private Variables
**********************************************************************/
static const uint16_t opmap[NUM_OPCODES] =
{
oNOP, /* opNOP */
oNEG, /* opNEG */
oABS, /* opABS */
oINC, /* opINC */
oDEC, /* opDEC */
oNOT, /* opNOT */
oADD, /* opADD */
oSUB, /* opSUB */
oMUL, /* opMUL */
oDIV, /* opDIV */
oMOD, /* opMOD */
oSLL, /* opSLL */
oSRL, /* opSRL */
oSRA, /* opSRA */
oOR, /* opOR */
oAND, /* opAND */
oEQUZ, /* opEQUZ */
oNEQZ, /* opNEQZ */
oLTZ, /* opLTZ */
oGTEZ, /* opGTEZ */
oGTZ, /* opGTZ */
oLTEZ, /* opLTEZ */
oEQU, /* opEQU */
oNEQ, /* opNEQ */
oLT, /* opLT */
oGTE, /* opGTE */
oGT, /* opGT */
oLTE, /* opLTE */
oBIT, /* opBIT */
oLDIH, /* opLDI -- integer load maps to 16-bit load */
oLDIB, /* opLDIB */
oLDIM, /* opLDIM */
oSTIH, /* opSTI - integer store maps to 16-bit store */
oSTIB, /* opSTIB */
oSTIM, /* opSTIM */
oDUPH, /* opDUP -- integer duplicate maps to 16-bit duplicate */
oPUSHS, /* opPUSHS */
oPOPS, /* opPOPS */
oRET, /* opRET */
oEND, /* opEND */
oFLOAT, /* opFLOAT */
oJEQUZ, /* opJEQUZ */
oJNEQZ, /* opJNEQZ */
oJMP, /* opJMP */
oJEQU, /* opJEQU */
oJNEQ, /* opJNEQ */
oJLT, /* opJLT */
oJGTE, /* opJGTE */
oJGT, /* opJGT */
oJLTE, /* opJLTE */
oLDH, /* opLD -- integer load maps to 16-bit load */
oLDH, /* opLDH */
oLDB, /* opLDB */
oLDM, /* opLDM */
oSTH, /* opST -- integer store maps to 16-bit store */
oSTB, /* opSTB */
oSTM, /* opSTM */
oLDXH, /* opLDX -- integer load maps to 16-bit load */
oLDXB, /* opLDXB */
oLDXM, /* opLDXM */
oSTXH, /* opSTX -- integer store maps to 16-bit store */
oSTXB, /* opSTXB */
oSTXM, /* opSTXM */
oLA, /* opLA */
oLAC, /* opLAC */
oPUSH, /* opPUSH */
oINDS, /* opINDS */
oLAX, /* opLAX */
oLIB, /* opLIB */
oLABEL, /* opLABEL */
oPCAL, /* opPCAL */
oLDSH, /* opLDS -- integer store maps to 16-bit load */
oLDSH, /* opLDSH */
oLDSB, /* opLDSB */
oLDSM, /* opLDSM */
oSTSH, /* opSTS -- integer store maps to 16-bit store */
oSTSB, /* opSTSB */
oSTSM, /* opSTSM */
oLDSXH, /* opLDSX -- integer load maps to 16-bit load */
oLDSXB, /* opLDSXB */
oLDSXM, /* opLDSXM */
oSTSXH, /* opSTSX -- integer store maps to 16-bit store */
oSTSXB, /* opSTSXB */
oSTSXM, /* opSTSXM */
oLAS, /* opLAS */
oLASX, /* opLASX */
oSYSIO, /* opSYSIO */
oLINE, /* opLINE */
};
/***********************************************************************
* Private Function Prototypes
***********************************************************************/
/***********************************************************************
* Private Functions
***********************************************************************/
static void
insn16_Generate(enum pcode_e opcode, uint16_t arg1, int32_t arg2);
/***********************************************************************
* Private Functions
***********************************************************************/
/***********************************************************************/
/* Disassemble an Op-code */
#if CONFIG_DEBUG
static inline void
insn16_DisassemblePCode(uint8_t opcode, uint8_t arg1, uint16_t arg2)
{
OPTYPE op;
op.op = opcode;
op.arg1 = arg1;
op.arg2 = arg2;
insn_DisassemblePCode(lstFile, &op);
}
#else
# define insn16_DisassemblePCode(op,a1,a2)
#endif
/***********************************************************************/
/* Generate an Op-Code */
static void
insn16_Generate(enum pcode_e opcode, uint16_t arg1, int32_t arg2)
{
uint16_t insn_opcode = opmap[opcode];
uint16_t arg16;
TRACE(lstFile,"[insn16_Generate:0x%02x->0x%04x]", opcode, insn_opcode);
poffAddProgByte(poffHandle, insn_opcode);
if (insn_opcode & o8)
{
if (arg1 > 0xff) error(eINTOVF);
poffAddProgByte(poffHandle, (uint8_t)arg1);
} /* End if */
if (insn_opcode & o16)
{
if ((arg2 < -32768) || (arg2 > 65535)) error(eINTOVF);
arg16 = (uint16_t)arg2;
poffAddProgByte(poffHandle, (uint8_t)(arg16 >> 8));
poffAddProgByte(poffHandle, (uint8_t)(arg16 & 0xff));
} /* End if */
/* Now, add the disassembled PCode to the list file. */
insn16_DisassemblePCode(insn_opcode, arg1, arg2);
} /* end insn16_Generate */
/***********************************************************************
* Public Functions
***********************************************************************/
void
insn_GenerateSimple(enum pcode_e opcode)
{
insn16_Generate(opcode, 0, 0);
}
/***********************************************************************/
void
insn_GenerateDataOperation(enum pcode_e opcode, int32_t data)
{
insn16_Generate(opcode, 0, data);
}
/***********************************************************************/
/* Data size for a multiple register operation (in bytes) is simply
* represented by that value at the top of the stack.
*/
void insn_GenerateDataSize(uint32_t dwDataSize)
{
insn16_Generate(opPUSH, 0, dwDataSize);
}
/***********************************************************************/
void
insn_GenerateFpOperation(uint8_t fpOpcode)
{
insn16_Generate(opFLOAT, fpOpcode, 0);
}
/***********************************************************************/
void
insn_GenerateIoOperation(uint16_t ioOpcode, uint16_t fileNumber)
{
insn16_Generate(opSYSIO, fileNumber, (int32_t)ioOpcode);
}
/***********************************************************************/
void
insn_BuiltInFunctionCall(uint16_t libOpcode)
{
insn16_Generate(opLIB, 0, (int32_t)libOpcode);
}
/***********************************************************************/
void
insn_GenerateLevelReference(enum pcode_e opcode, uint16_t level, int32_t offset)
{
insn16_Generate(opcode, level, offset);
}
/***********************************************************************/
void
insn_GenerateProcedureCall(uint16_t level, int32_t offset)
{
insn16_Generate(opPCAL, level, offset);
}
/***********************************************************************/
void
insn_GenerateLineNumber(uint16_t includeNumber, uint32_t lineNumber)
{
insn16_Generate(opLINE, includeNumber, lineNumber);
}
/***********************************************************************/
void
insn_SetStackLevel(uint32_t level)
{
/* Do nothing */
}
+140
View File
@@ -0,0 +1,140 @@
/**********************************************************************
* pgetopcode.c
* P-Code access utilities
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include "keywords.h"
#include "podefs.h"
#include "pinsn16.h"
#include "paslib.h"
#include "pofflib.h"
#include "pinsn.h"
/**********************************************************************
* Private Function Prototypes
**********************************************************************/
/**********************************************************************
* Global Variables
**********************************************************************/
static int16_t g_bEndIn = 0; /* 1 = oEND pcode or EOF received */
/**********************************************************************
* Private Variables
**********************************************************************/
/**********************************************************************
* Private Functions
**********************************************************************/
/**********************************************************************
* Global Functions
**********************************************************************/
/**********************************************************************/
uint32_t insn_GetOpCode(poffHandle_t handle, OPTYPE *ptr)
{
uint32_t opsize = 1;
int c;
TRACE(stderr, "[insn_GetOpCode]");
/* If we are not already at the EOF, read the next character from
* the input stream.
*/
if (!g_bEndIn)
c = poffGetProgByte(handle);
else
c = EOF;
/* Check for end of file. We may have previously parsed oEND which
* is a 'logical' end of file for a pascal program (but not a unit)
* or we may be at the physical end of the file wihout encountering
* oEND (typical for a UNIT file).
*/
if ((g_bEndIn) || (c == EOF))
{
ptr->op = oEND;
ptr->arg1 = 0;
ptr->arg2 = 0;
} /* end if */
else
{
ptr->op = c;
g_bEndIn = (ptr->op == oEND);
if (ptr->op & o8)
{
ptr->arg1 = poffGetProgByte(handle);
opsize++;
}
else
{
ptr->arg1 = 0;
}
if (ptr->op & o16)
{
ptr->arg2 = (poffGetProgByte(handle) << 8);
ptr->arg2 |= (poffGetProgByte(handle) & 0xff);
opsize += 2;
}
else
{
ptr->arg2 = 0;
}
}
return opsize;
}
/**********************************************************************/
void insn_ResetOpCodeRead(poffHandle_t handle)
{
poffResetAccess(handle);
g_bEndIn = 0;
}
/***********************************************************************/
+149
View File
@@ -0,0 +1,149 @@
/**********************************************************************
* preloc.c
* Perform P-Code relocations
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include "keywords.h"
#include "pdefs.h"
#include "pedefs.h"
#include "podefs.h"
#include "pinsn16.h"
#include "pofflib.h"
#include "perr.h"
#include "pinsn.h"
/**********************************************************************
* Definitions
**********************************************************************/
/**********************************************************************
* Private Type Definitions
**********************************************************************/
/**********************************************************************
* Private Function Prototypes
**********************************************************************/
/**********************************************************************
* Global Variables
**********************************************************************/
/**********************************************************************
* Private Variables
**********************************************************************/
/**********************************************************************
* Private Functions
**********************************************************************/
int insn_Relocate(OPTYPE *op, uint32_t pcOffset, uint32_t roOffset)
{
switch (op->op)
{
/* Catch each instruction that references the read-only data
* section.
*/
case oLAC:
/* Add the offset to the read-only data section */
op->arg2 += roOffset;
break;
/* Catch each instruction that references the text section
* data via an offset.
*/
case oPCAL: /* Procedure / Function calls */
case oJMP: /* Unconditional jump */
case oJEQUZ: /* Jump on unary comparisons with zero */
case oJNEQZ:
case oJLTZ:
case oJGTEZ:
case oJGTZ:
case oJLTEZ:
case oJEQU: /* Jump on binary comparisons */
case oJNEQ:
case oJLT:
case oJGTE:
case oJGT:
case oJLTE:
/* Add the offset to the text section */
op->arg2 += pcOffset;
break;
/* Return an end of file indication if oEND encountered */
case oEND:
return 1;
/* Otherwise, it is not an interesting opcode */
default:
break;
}
/* Return 0 on all opcodes other than oEND */
return 0;
}
/***********************************************************************/
void insn_FixupProcedureCall(uint8_t *progData, uint32_t symValue)
{
/* Sanity checking */
if (progData[0] != oPCAL)
fatal(ePOFFCONFUSION);
if (symValue > 0xffff)
fatal(eBADSHORTINT);
/* Perform the relocation */
progData[2] = symValue >> 8;
progData[3] = symValue & 0xff;
}
/***********************************************************************/
+90
View File
@@ -0,0 +1,90 @@
############################################################################
# insn16/plist/Makefile
#
# Copyright (C) 2008 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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
#
PLISTDIR = ${shell pwd}
INSNDIR = $(PLISTDIR)/..
PASCAL = $(PLISTDIR)/../..
include $(PASCAL)/Make.config
include $(PASCAL)/Make.defs
INCDIR = $(PASCAL)/include
LIBDIR = $(PASCAL)/lib
BINDIR = $(PASCAL)/bin16
#
# Tools
#
EXTRA_INCLUDES = -I$(INSNDIR)/include
INCLUDES += $(EXTRA_INCLUDES)
CFLAGS += $(EXTRA_INCLUDES)
#
# Objects and targets
#
PLISTSRCS = plist.c
PLISTOBJS = $(PLISTSRCS:.c=.o)
OBJS = $(PLISTOBJS)
all: plist
.PHONY: all plist 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)/plist: check_libs $(PLISTOBJS)
$(CC) -o $@ $(LDFLAGS) $(PLISTOBJS) -lpoff -linsn -lpas
plist: $(BINDIR)/plist
clean:
$(RM) plist *.o core *~
+360
View File
@@ -0,0 +1,360 @@
/**********************************************************************
* plist.c
* POFF file lister
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#define _GNU_SOURCE
#include <getopt.h>
#include "keywords.h"
#include "pdefs.h"
#include "podefs.h"
#include "pinsn16.h"
#include "pedefs.h"
#include "pofflib.h"
#include "paslib.h"
#include "pinsn.h"
/**********************************************************************
* Definitions
**********************************************************************/
#define MAX_STRING 80
/**********************************************************************
* Private Data
**********************************************************************/
static char *poffFileName = NULL;
static int showFileHeader = 0;
static int showSectionHeaders = 0;
static int showSymbols = 0;
static int showRelocs = 0;
static int disassemble = 0;
/**********************************************************************
* Private Constant Data
**********************************************************************/
static const struct option long_options[] =
{
{"all", 0, NULL, 'a'},
{"file-header", 0, NULL, 'h'},
{"section-headers", 0, NULL, 'S'},
{"symbols", 0, NULL, 's'},
{"relocs", 0, NULL, 'r'},
{"disassemble", 0, NULL, 'd'},
{"help", 0, NULL, 'H'},
{NULL, 0, NULL, 0}
};
/**********************************************************************
* Private Function Prototypes
**********************************************************************/
static void showUsage (const char *progname);
static void parseArgs (int argc, char **argv);
static void dumpProgramData (poffHandle_t poffHandle);
/**********************************************************************
* Global Functions
**********************************************************************/
int main (int argc, char *argv[], char *envp[])
{
FILE *object; /* Object file pointer */
poffHandle_t poffHandle; /* Handle for POFF object */
char fileName[FNAME_SIZE+1]; /* Object file name */
uint16_t errCode; /* See pedefs.h */
/* Parse the command line arguments */
parseArgs(argc, argv);
/* Open source POFF file -- Use .o or command line extension, if supplied */
(void) extension (poffFileName, "o", fileName, 0);
if (!(object = fopen (fileName, "rb")))
{
printf ("Error opening %s\n", fileName);
exit (1);
} /* end if */
/* Read the POFF file */
poffHandle = poffCreateHandle();
if (poffHandle == NULL)
{
printf ("Could not get POFF handler\n");
exit (1);
}
errCode = poffReadFile(poffHandle, object);
if (errCode != eNOERROR)
{
printf ("Could not read POFF file\n");
exit (1);
}
/* Dump the File Header */
if (showFileHeader)
{
poffDumpFileHeader(poffHandle, stdout);
}
/* Dump the Section Headers */
if (showSectionHeaders)
{
poffDumpSectionHeaders(poffHandle, stdout);
}
/* Dump the symbol table */
if (showSymbols)
{
poffDumpSymbolTable(poffHandle, stdout);
}
/* Dump the relocation table */
if (showRelocs)
{
poffDumpRelocTable(poffHandle, stdout);
}
/* Dump the program data section -- Main Loop */
if (disassemble)
{
dumpProgramData(poffHandle);
}
/* Close files and release objects */
poffDestroyHandle(poffHandle);
(void)fclose(object);
return 0;
} /* end main */
/**********************************************************************
* Private Functions
**********************************************************************/
static void showUsage(const char *progname)
{
fprintf(stderr, "Usage:\n");
fprintf(stderr, " %s [options] <poff-filename>\n",
progname);
fprintf(stderr, "options:\n");
fprintf(stderr, " -a --all Equivalent to: -h -S -s -r -d\n");
fprintf(stderr, " -h --file-header Display the POFF file header\n");
fprintf(stderr, " -S --section-headers Display the sections' header\n");
fprintf(stderr, " -s --symbols Display the symbol table\n");
fprintf(stderr, " -r --relocs Display the relocations\n");
fprintf(stderr, " -d --disassemble Display disassembled text\n");
fprintf(stderr, " -H --help Display this information\n");
exit(1);
}
/***********************************************************************/
static void parseArgs(int argc, char **argv)
{
int option_index;
int c;
/* Check for existence of filename argument */
if (argc < 2)
{
fprintf(stderr, "ERROR: POFF filename required\n");
showUsage(argv[0]);
} /* end if */
/* Parse the command line options */
do
{
c = getopt_long (argc, argv, "ahSsrdH",
long_options, &option_index);
if (c != -1)
{
switch (c)
{
case 'a' :
showFileHeader = 1;
showSectionHeaders = 1;
showSymbols = 1;
showRelocs = 1;
disassemble = 1;
break;
case 'h' :
showFileHeader = 1;
break;
case 'S' :
showSectionHeaders = 1;
break;
case 's' :
showSymbols = 1;
break;
case 'r' :
showRelocs = 1;
break;
case 'd' :
disassemble = 1;
break;
case 'H' :
showUsage(argv[0]);
break;
default:
/* Shouldn't happen */
fprintf(stderr, "ERROR: Unrecognized option\n");
showUsage(argv[0]);
}
}
}
while (c != -1);
/* Get the name of the p-code file(s) from the last argument(s) */
if (optind != argc-1)
{
fprintf(stderr, "ERROR: POFF filename required as final argument\n");
showUsage(argv[0]);
}
/* Save the POFF file name */
poffFileName = argv[argc-1];
}
/***********************************************************************/
static void dumpProgramData(poffHandle_t poffHandle)
{
poffLibLineNumber_t *lastln; /* Previous line number reference */
poffLibLineNumber_t *ln; /* Current line number reference */
uint32_t pc; /* Program counter */
OPTYPE op; /* Opcode */
int opSize; /* Size of the opcode */
int inch; /* Input char */
/* Read the line number entries from the POFF file */
poffReadLineNumberTable(poffHandle);
/* Dump the program data section -- DumpProgramData Loop */
pc = 0;
lastln = NULL;
while ((inch = poffGetProgByte(poffHandle)) != EOF)
{
/* Get opcode arguments (if any) */
op.op = (uint8_t) inch;
op.arg1 = 0;
op.arg2 = 0;
opSize = 1;
if (op.op & o8)
{
op.arg1 = poffGetProgByte(poffHandle);
opSize += 1;
}
if (op.op & o16 )
{
op.arg2 = poffGetProgByte(poffHandle) << 8;
op.arg2 |= poffGetProgByte(poffHandle);
opSize += 2;
} /* end if */
/* Find the line number associated with this line */
ln = poffFindLineNumber(pc);
if ((ln) && (ln != lastln))
{
/* Print the line number line */
printf("\n%s:%ld\n", ln->filename, ln->lineno);
/* This will suppress reporting the same line number
* repeatedly.
*/
lastln = ln;
}
/* Print the address then the opcode on stdout */
fprintf(stdout, "%08lx ", pc);
insn_DisassemblePCode(stdout, &op);
/* Bump the PC to the next address */
pc += opSize;
} /* end while */
/* Release buffers associated with line number information */
poffReleaseLineNumberTable();
} /* end dumpProgramData */
/***********************************************************************/
+92
View File
@@ -0,0 +1,92 @@
############################################################################
# insn16/prun/Makefile
# Host system makefile
#
# Copyright (C) 2008 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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)/bin16
#
# 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) -lpoff -linsn -lpas
popt: $(BINDIR)/popt
clean:
$(RM) popt *.o core *~
+906
View File
@@ -0,0 +1,906 @@
/**********************************************************************
* pcopt.c
* Constant Expression Optimizations
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include <stdio.h>
#include "keywords.h"
#include "pdefs.h"
#include "pinsn16.h"
#include "paslib.h"
#include "popt.h"
#include "polocal.h"
#include "pcopt.h"
/**********************************************************************/
int16_t unaryOptimize(void)
{
int16_t nchanges = 0;
register uint16_t temp;
register int16_t i;
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 ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB))
{
/* Turn the oPUSHB into an oPUSH op (temporarily) */
if (pptr[i]->op == oPUSHB)
{
pptr[i]->op = oPUSH;
pptr[i]->arg2 = pptr[i]->arg1;
pptr[i]->arg1 = 0;
} /* end if */
switch (pptr[i+1]->op)
{
/* Delete unary operators on constants */
case oNEG :
pptr[i]->arg2 = -(pptr[i]->arg2);
deletePcode(i+1);
nchanges++;
break;
case oABS :
if (signExtend16(pptr[i]->arg2) < 0)
pptr[i]->arg2 = -signExtend16(pptr[i]->arg2);
deletePcode(i+1);
nchanges++;
break;
case oINC :
(pptr[i]->arg2)++;
deletePcode(i+1);
nchanges++;
break;
case oDEC :
(pptr[i]->arg2)--;
deletePcode(i+1);
nchanges++;
break;
case oNOT :
pptr[i]->arg2 = ~(pptr[i]->arg2);
deletePcode(i+1);
nchanges++;
break;
/* Simplify binary operations on constants */
case oADD :
if (pptr[i]->arg2 == 0)
{
deletePcodePair(i, (i+1));
nchanges++;
} /* end if */
else if (pptr[i]->arg2 == 1)
{
pptr[i+1]->op = oINC;
deletePcode(i);
nchanges++;
} /* end else if */
else if (pptr[i]->arg2 == (uint16_t)-1)
{
pptr[i+1]->op = oDEC;
deletePcode(i);
nchanges++;
} /* end else if */
else i++;
break;
case oSUB :
if (pptr[i]->arg2 == 0)
{
deletePcodePair(i, (i+1));
nchanges++;
} /* end if */
else if (pptr[i]->arg2 == 1)
{
pptr[i+1]->op = oDEC;
deletePcode(i);
nchanges++;
} /* end else if */
else if (pptr[i]->arg2 == (uint16_t)-1)
{
pptr[i+1]->op = oINC;
deletePcode(i);
nchanges++;
} /* end else if */
else i++;
break;
case oMUL :
case oDIV :
temp = 0;
switch (pptr[i]->arg2)
{
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++;
pptr[i]->arg2 = temp;
if (pptr[i+1]->op == oMUL)
pptr[i+1]->op = oSLL;
else
pptr[i+1]->op = oSRA;
nchanges++;
i++;
break;
default :
i++;
break;
} /* end switch */
break;
case oSLL :
case oSRL :
case oSRA :
case oOR :
if (pptr[i]->arg2 == 0)
{
deletePcodePair(i, (i+1));
nchanges++;
} /* end if */
else i++;
break;
case oAND :
if (pptr[i]->arg2 == 0xffff)
{
deletePcodePair(i, (i+1));
nchanges++;
} /* end if */
else i++;
break;
/* Delete comparisons of constants to zero */
case oEQUZ :
if (pptr[i]->arg2 == 0) pptr[i]->arg2 = -1;
else pptr[i]->arg2 = 0;
deletePcode(i+1);
nchanges++;
break;
case oNEQZ :
if (pptr[i]->arg2 != 0)
pptr[i]->arg2 = -1;
else
pptr[i]->arg2 = 0;
deletePcode(i+1);
nchanges++;
break;
case oLTZ :
if (signExtend16(pptr[i]->arg2) < 0)
pptr[i]->arg2 = -1;
else
pptr[i]->arg2 = 0;
deletePcode(i+1);
nchanges++;
break;
case oGTEZ :
if (signExtend16(pptr[i]->arg2) >= 0)
pptr[i]->arg2 = -1;
else
pptr[i]->arg2 = 0;
deletePcode(i+1);
nchanges++;
break;
case oGTZ :
if (pptr[i]->arg2 > 0) pptr[i]->arg2 = -1;
else pptr[i]->arg2 = 0;
deletePcode(i+1);
nchanges++;
break;
case oLTEZ :
if (pptr[i]->arg2 <= 0) pptr[i]->arg2 = -1;
else pptr[i]->arg2 = 0;
deletePcode(i+1);
nchanges++;
break;
/* Simplify comparisons with certain constants */
case oEQU :
if (pptr[i]->arg2 == 0)
{
pptr[i+1]->op = oEQUZ;
deletePcode(i);
nchanges++;
} /* end if */
else if (pptr[i]->arg2 == 1)
{
pptr[i]->op = oDEC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oEQUZ;
nchanges++;
} /* end else if */
else if (signExtend16(pptr[i]->arg2) == -1)
{
pptr[i]->op = oINC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oEQUZ;
nchanges++;
} /* end else if */
else i++;
break;
case oNEQ :
if (pptr[i]->arg2 == 0)
{
pptr[i+1]->op = oNEQZ;
deletePcode(i);
nchanges++;
} /* end if */
else if (pptr[i]->arg2 == 1)
{
pptr[i]->op = oDEC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oNEQZ;
nchanges++;
} /* end else if */
else if (signExtend16(pptr[i]->arg2) == -1)
{
pptr[i]->op = oINC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oNEQZ;
nchanges++;
} /* end else if */
else i++;
break;
case oLT :
if (pptr[i]->arg2 == 0)
{
pptr[i+1]->op = oLTZ;
deletePcode(i);
nchanges++;
} /* end if */
else if (pptr[i]->arg2 == 1)
{
pptr[i]->op = oDEC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oLTZ;
nchanges++;
} /* end else if */
else if (signExtend16(pptr[i]->arg2) == -1)
{
pptr[i]->op = oINC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oLTZ;
nchanges++;
} /* end else if */
else i++;
break;
case oGTE :
if (pptr[i]->arg2 == 0)
{
pptr[i+1]->op = oGTEZ;
deletePcode(i);
nchanges++;
} /* end if */
else if (pptr[i]->arg2 == 1)
{
pptr[i]->op = oDEC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oGTEZ;
nchanges++;
} /* end else if */
else if (signExtend16(pptr[i]->arg2) == -1)
{
pptr[i]->op = oINC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oGTEZ;
nchanges++;
} /* end else if */
else i++;
break;
case oGT :
if (pptr[i]->arg2 == 0)
{
pptr[i+1]->op = oGTZ;
deletePcode(i);
nchanges++;
} /* end if */
else if (pptr[i]->arg2 == 1)
{
pptr[i]->op = oDEC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oGTZ;
nchanges++;
} /* end else if */
else if (signExtend16(pptr[i]->arg2) == -1)
{
pptr[i]->op = oINC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oGTZ;
nchanges++;
} /* end else if */
else i++;
break;
case oLTE :
if (pptr[i]->arg2 == 0)
{
pptr[i+1]->op = oLTEZ;
deletePcode(i);
nchanges++;
} /* end if */
else if (pptr[i]->arg2 == 1)
{
pptr[i]->op = oDEC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oLTEZ;
nchanges++;
} /* end else if */
else if (signExtend16(pptr[i]->arg2) == -1)
{
pptr[i]->op = oINC;
pptr[i]->arg2 = 0;
pptr[i+1]->op = oLTEZ;
nchanges++;
} /* end else if */
else i++;
break;
/* Simplify or delete condition branches on constants */
case oJEQUZ :
if (pptr[i]->arg2 == 0)
{
pptr[i+1]->op = oJMP;
deletePcode(i);
} /* end if */
else
deletePcodePair(i, (i+1));
nchanges++;
break;
case oJNEQZ :
if (pptr[i]->arg2 != 0)
{
pptr[i+1]->op = oJMP;
deletePcode(i);
} /* end if */
else
deletePcodePair(i, (i+1));
nchanges++;
break;
case oJLTZ :
if (signExtend16(pptr[i]->arg2) < 0)
{
pptr[i+1]->op = oJMP;
deletePcode(i);
} /* end if */
else
deletePcodePair(i, (i+1));
nchanges++;
break;
case oJGTEZ :
if (signExtend16(pptr[i]->arg2) >= 0)
{
pptr[i+1]->op = oJMP;
deletePcode(i);
} /* end if */
else
deletePcodePair(i, (i+1));
nchanges++;
break;
case oJGTZ :
if (pptr[i]->arg2 > 0)
{
pptr[i+1]->op = oJMP;
deletePcode(i);
} /* end if */
else
deletePcodePair(i, (i+1));
nchanges++;
break;
case oJLTEZ :
if (pptr[i]->arg2 <= 0)
{
pptr[i+1]->op = oJMP;
deletePcode(i);
} /* end if */
else
deletePcodePair(i, (i+1));
nchanges++;
break;
default :
i++;
break;
} /* end switch */
/* If the oPUSH instruction is still there, see if we can now */
/* represent it with an oPUSHB instruction */
if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
{
pptr[i]->op = oPUSHB;
pptr[i]->arg1 = pptr[i]->arg2;
pptr[i]->arg2 = 0;
} /* end if */
} /* end if */
/* Delete multiple modifications of DSEG pointer */
else if (pptr[i]->op == oINDS)
{
if (pptr[i+1]->op == oINDS)
{
pptr[i]->arg2 += pptr[i+1]->arg2;
deletePcode(i+1);
} /* end if */
else i++;
} /* end else if */
else i++;
} /* end while */
return (nchanges);
} /* end unaryOptimize */
/**********************************************************************/
int16_t binaryOptimize(void)
{
int16_t nchanges = 0;
register int16_t stmp16;
register int16_t i;
TRACE(stderr, "[binaryOptimize]");
/* At least two pcodes are needed to perform the following binary */
/* operator optimizations */
i = 0;
while (i < nops-2)
{
if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB))
{
if ((pptr[i+1]->op == oPUSH) || (pptr[i+1]->op == oPUSHB))
{
/* Turn the oPUSHBs into an oPUSHs op (temporarily) */
if (pptr[i]->op == oPUSHB)
{
pptr[i]->op = oPUSH;
pptr[i]->arg2 = pptr[i]->arg1;
pptr[i]->arg1 = 0;
} /* end if */
if (pptr[i+1]->op == oPUSHB)
{
pptr[i+1]->op = oPUSH;
pptr[i+1]->arg2 = pptr[i+1]->arg1;
pptr[i+1]->arg1 = 0;
} /* end if */
switch (pptr[i+2]->op)
{
case oADD :
pptr[i]->arg2 += pptr[i+1]->arg2;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oSUB :
pptr[i]->arg2 -= pptr[i+1]->arg2;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oMUL :
pptr[i]->arg2 *= pptr[i+1]->arg2;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oDIV :
stmp16 = pptr[i]->arg2 / signExtend16(pptr[i+1]->arg2);
pptr[i]->arg2 = stmp16;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oMOD :
pptr[i]->arg2 %= pptr[i+1]->arg2;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oSLL :
pptr[i]->arg2 <<= pptr[i+1]->arg2;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oSRL :
pptr[i]->arg2 >>= pptr[i+1]->arg2;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oSRA :
stmp16 = (((int16_t)pptr[i]->arg2) >> pptr[i+1]->arg2);
pptr[i]->arg2 = (uint16_t)stmp16;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oOR :
pptr[i]->arg2 |= pptr[i+1]->arg2;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oAND :
pptr[i]->arg2 &= pptr[i+1]->arg2;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oEQU :
if (pptr[i]->arg2 == pptr[i+1]->arg2) pptr[i]->arg2 = -1;
else pptr[i]->arg2 = 0;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oNEQ :
if ((int16_t)pptr[i]->arg2 != (int16_t)pptr[i+1]->arg2)
pptr[i]->arg2 = -1;
else
pptr[i]->arg2 = 0;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oLT :
if ((int16_t)pptr[i]->arg2 < (int16_t)pptr[i+1]->arg2)
pptr[i]->arg2 = -1;
else
pptr[i]->arg2 = 0;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oGTE :
if ((int16_t)pptr[i]->arg2 >= (int16_t)pptr[i+1]->arg2)
pptr[i]->arg2 = -1;
else
pptr[i]->arg2 = 0;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oGT :
if ((int16_t)pptr[i]->arg2 > (int16_t)pptr[i+1]->arg2)
pptr[i]->arg2 = -1;
else
pptr[i]->arg2 = 0;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
case oLTE :
if ((int16_t)pptr[i]->arg2 <= (int16_t)pptr[i+1]->arg2)
pptr[i]->arg2 = -1;
else
pptr[i]->arg2 = 0;
deletePcodePair((i+1), (i+2));
nchanges++;
break;
default :
i++;
break;
} /* end switch */
/* If the oPUSH instruction is still there, see if we can now */
/* represent it with an oPUSHB instruction */
if (pptr[i] && (pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
{
pptr[i]->op = oPUSHB;
pptr[i]->arg1 = pptr[i]->arg2;
pptr[i]->arg2 = 0;
} /* end if */
if (pptr[i+1] && (pptr[i+1]->op == oPUSH) && (pptr[i+1]->arg2 < 256))
{
pptr[i+1]->op = oPUSHB;
pptr[i+1]->arg1 = pptr[i+1]->arg2;
pptr[i+1]->arg2 = 0;
} /* end if */
} /* end if */
/* A single (constant) pcode is sufficient to perform the */
/* following binary operator optimizations */
else if ((pptr[i+1]->op == oLDSH) || (pptr[i+1]->op == oLDSB) ||
(pptr[i+1]->op == oLAS) || (pptr[i+1]->op == oLAC))
{
/* Turn the oPUSHB into a oPUSH op (temporarily) */
if (pptr[i]->op == oPUSHB)
{
pptr[i]->op = oPUSH;
pptr[i]->arg2 = pptr[i]->arg1;
pptr[i]->arg1 = 0;
} /* end if */
switch (pptr[i+2]->op)
{
case oADD :
if (pptr[i]->arg2 == 0)
{
deletePcodePair(i, (i+2));
nchanges++;
} /* end if */
else if (pptr[i]->arg2 == 1)
{
pptr[i+2]->op = oINC;
deletePcode(i);
nchanges++;
} /* end else if */
else if (pptr[i]->arg2 == (uint16_t)-1)
{
pptr[i+2]->op = oDEC;
deletePcode(i);
nchanges++;
} /* end else if */
else i++;
break;
case oSUB :
if (pptr[i]->arg2 == 0)
{
pptr[i]->op = oNEG;
deletePcode(i);
nchanges++;
} /* end if */
else i++;
break;
case oMUL :
stmp16 = 0;
switch (pptr[i]->arg2)
{
case 1 :
deletePcodePair(i, (i+2));
nchanges++;
break;
case 16384 : stmp16++;
case 8192 : stmp16++;
case 4096 : stmp16++;
case 2048 : stmp16++;
case 1024 : stmp16++;
case 512 : stmp16++;
case 256 : stmp16++;
case 128 : stmp16++;
case 64 : stmp16++;
case 32 : stmp16++;
case 16 : stmp16++;
case 8 : stmp16++;
case 4 : stmp16++;
case 2 : stmp16++;
pptr[i]->op = pptr[i+1]->op;
pptr[i]->arg1 = pptr[i+1]->arg1;
pptr[i]->arg2 = pptr[i+1]->arg2;
pptr[i+1]->op = oPUSH;
pptr[i+1]->arg1 = 0;
pptr[i+1]->arg2 = stmp16;
pptr[i+2]->op = oSLL;
nchanges++;
i++;
break;
default :
i++;
break;
} /* end switch */
break;
case oOR :
if (pptr[i]->arg2 == 0)
{
deletePcodePair(i, (i+2));
nchanges++;
} /* end if */
else i++;
break;
case oAND :
if (pptr[i]->arg2 == 0xffff)
{
deletePcodePair(i, (i+2));
nchanges++;
} /* end if */
else i++;
break;
case oEQU :
if (pptr[i]->arg2 == 0)
{
pptr[i+2]->op = oEQUZ;
deletePcode(i);
nchanges++;
} /* end if */
else i++;
break;
case oNEQ :
if (pptr[i]->arg2 == 0)
{
pptr[i+2]->op = oNEQZ;
deletePcode(i);
nchanges++;
} /* end if */
else i++;
break;
case oLT :
if (pptr[i]->arg2 == 0)
{
pptr[i+2]->op = oGTEZ;
deletePcode(i);
nchanges++;
} /* end if */
else i++;
break;
case oGTE :
if (pptr[i]->arg2 == 0)
{
pptr[i+2]->op = oLTZ;
deletePcode(i);
nchanges++;
} /* end if */
else i++;
break;
case oGT :
if (pptr[i]->arg2 == 0)
{
pptr[i+2]->op = oLTEZ;
deletePcode(i);
nchanges++;
} /* end if */
else i++;
break;
case oLTE :
if (pptr[i]->arg2 == 0)
{
pptr[i+2]->op = oGTZ;
deletePcode(i);
nchanges++;
} /* end if */
else i++;
break;
default :
i++;
break;
} /* end switch */
/* If the oPUSH instruction is still there, see if we can now */
/* represent it with an oPUSHB instruction */
if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256))
{
pptr[i]->op = oPUSHB;
pptr[i]->arg1 = pptr[i]->arg2;
pptr[i]->arg2 = 0;
} /* end if */
} /* end else if */
else i++;
} /* end if */
/* Misc improvements on binary operators */
else if (pptr[i]->op == oNEG)
{
/* Negation followed by add is subtraction */
if (pptr[i+1]->op == oADD)
{
pptr[i+1]->op = oSUB;
deletePcode(i);
nchanges++;
}
/* Negation followed by subtraction is addition */
else if (pptr[i]->op == oSUB)
{
pptr[i+1]->op = oADD;
deletePcode(i);
nchanges++;
}
else i++;
}
else i++;
} /* end while */
return (nchanges);
} /* end binaryOptimize */
/**********************************************************************/
+53
View File
@@ -0,0 +1,53 @@
/***************************************************************************
* pcopt.h
* External Declarations associated with PCOPT.C
*
* Copyright (C) 200-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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
/***************************************************************************
* Included Files
***************************************************************************/
#include <stdint.h>
/***************************************************************************
* Global Function Prototypes
***************************************************************************/
extern int16_t unaryOptimize(void);
extern int16_t binaryOptimize(void);
#endif /* __PCOPT_H */
+473
View File
@@ -0,0 +1,473 @@
/**********************************************************************
* pfopt.c
* Finalization of optimized image
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "keywords.h"
#include "pdefs.h"
#include "podefs.h"
#include "pedefs.h"
#include "pinsn16.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_t pc;
uint32_t opsize;
/* 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 (op.op == oLABEL)
{
poffAddToDefinedLabelTable(op.arg2, pc);
}
else if (op.op == oLINE)
{
poffAddLineNumber(poffHandle, op.arg2, op.arg1, pc);
}
else
{
insn_AddTmpOpCode(poffProgHandle, &op);
pc += opsize;
}
}
while (op.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;
int32_t symIndex;
int32_t 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.
*/
int32_t value = poffGetPcForDefinedLabel(symbol.value);
if (value < 0)
{
DEBUG(stdout, "Failed to find label L%04lx\n", symbol.value);
fatal(ePOFFCONFUSION);
}
else
{
/* Replace the label 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_t pc;
uint32_t 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 (op.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.
*/
int32_t value = poffGetPcForDefinedLabel(op.arg2);
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.
*/
op.arg2 = (uint16_t)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(op.arg2);
if (value >= 0)
{
/* Use the value zero now */
op.arg2 = 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", op.arg2);
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.
*/
int32_t value = poffGetPcForDefinedLabel(op.arg2);
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.
*/
op.arg2 = (uint16_t)value;
}
else
{
DEBUG(stdout, "Failed to find jump label L%04x\n", op.arg2);
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 (op.op != oEND);
/* Replace the original program data with the new program data */
poffReplaceProgData(poffHandle, poffProgHandle);
}
/**********************************************************************/
static void pass4(poffHandle_t poffHandle)
{
uint32_t entryLabel;
int32_t entryOffset;
uint8_t 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);
/* We do not use the debug function information so we do not bother
* to fixup the label references. Just discard this information.
*/
poffDiscardDebugFuncInfo(poffHandle);
/* 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);
/* Reset for next pass */
insn_ResetOpCodeRead(poffHandle);
insn_ResetTmpOpCodeWrite(poffProgHandle);
/* Finally, replace file header entry point with the I-space offset */
pass4(poffHandle);
/* Clean up after ourselves */
poffReleaseLabelReferences();
}
/**********************************************************************/
+54
View File
@@ -0,0 +1,54 @@
/***************************************************************************
* pfopt.h
* External Declarations associated with pfopt.c
*
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 */
+450
View File
@@ -0,0 +1,450 @@
/**********************************************************************
* pjopt.c
* Branch Optimizations
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include <stdio.h>
#include "keywords.h"
#include "pdefs.h"
#include "pinsn16.h"
#include "popt.h"
#include "polocal.h"
#include "pjopt.h"
/**********************************************************************/
int16_t BranchOptimize (void)
{
int16_t nchanges = 0;
register int16_t 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 */
/**********************************************************************/
+52
View File
@@ -0,0 +1,52 @@
/***************************************************************************
* pjopt.h
* External Declarations associated with pjopt.c
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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
/***************************************************************************
* Included Files
***************************************************************************/
#include <stdint.h>
/***************************************************************************
* Public Function Prototypes
***************************************************************************/
int16_t BranchOptimize(void);
#endif /* __PJOPT_H */
+250
View File
@@ -0,0 +1,250 @@
/**********************************************************************
* plopt.c
* Load/Store Optimizations
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include <stdio.h>
#include "keywords.h"
#include "pdefs.h"
#include "pinsn16.h"
#include "popt.h"
#include "polocal.h"
#include "plopt.h"
/**********************************************************************/
int16_t LoadOptimize(void)
{
uint16_t val;
int16_t nchanges = 0;
register int16_t i;
TRACE(stderr, "[LoadOptimize]");
/* At least two pcodes are need to perform Load optimizations */
i = 0;
while (i < nops-1)
{
switch (pptr[i]->op)
{
/* Eliminate duplicate loads */
case oLDSH :
if ((pptr[i+1]->op == oLDSH) &&
(pptr[i+1]->arg1 == pptr[i]->arg1) &&
(pptr[i+1]->arg2 == pptr[i]->arg2))
{
pptr[i+1]->op = oDUPH;
pptr[i+1]->arg1 = 0;
pptr[i+1]->arg2 = 0;
nchanges++;
i += 2;
} /* end if */
else i++;
break;
/* Convert loads indexed by a constant to unindexed loads */
case oPUSH :
case oPUSHB :
/* Get the index value */
if (pptr[i]->op == oPUSH)
{
val = pptr[i]->arg2;
}
else
{
val = pptr[i]->arg1;
}
/* If the following instruction is a load, add the constant
* index value to the address and switch the opcode to the
* unindexed form.
*/
if (pptr[i+1]->op == oLDSXH)
{
pptr[i+1]->op = oLDSH;
pptr[i+1]->arg2 += val;
deletePcode (i);
nchanges++;
} /* end if */
else if (pptr[i+1]->op == oLASX)
{
pptr[i+1]->op = oLAS;
pptr[i+1]->arg2 += val;
deletePcode (i);
nchanges++;
} /* end else if */
else if (pptr[i+1]->op == oLDSXB)
{
pptr[i+1]->op = oLDSB;
pptr[i+1]->arg2 += val;
deletePcode (i);
nchanges++;
} /* end if */
else if (pptr[i+1]->op == oLDSXM)
{
pptr[i+1]->op = oLDSM;
pptr[i+1]->arg2 += val;
deletePcode (i);
nchanges++;
} /* end if */
else if (val < 256)
{
pptr[i]->op = oPUSHB;
pptr[i]->arg1 = val;
pptr[i]->arg2 = 0;
i++;
} /* end else if */
else i++;
break;
default :
i++;
break;
} /* end switch */
} /* end while */
return (nchanges);
} /* end LoadOptimize */
/**********************************************************************/
int16_t StoreOptimize (void)
{
uint16_t val;
int16_t nchanges = 0;
register int16_t i;
TRACE(stderr, "[StoreOptimize]");
/* At least two pcodes are need to perform the following Store */
/* optimizations */
i = 0;
while (i < nops-1)
{
switch (pptr[i]->op)
{
/* Eliminate store followed by load */
case oSTSH :
if ((pptr[i+1]->op == oLDSH) &&
(pptr[i+1]->arg1 == pptr[i]->arg1) &&
(pptr[i+1]->arg2 == pptr[i]->arg2))
{
pptr[i+1]->op = oSTSH;
pptr[i]->op = oDUPH;
pptr[i]->arg1 = 0;
pptr[i]->arg2 = 0;
nchanges++;
i += 2;
} /* end if */
else i++;
break;
/* Convert stores indexed by a constant to unindexed stores */
case oPUSH :
/* Get the index value */
if (pptr[i]->op == oPUSH)
{
val = pptr[i]->arg2;
}
else
{
val = pptr[i]->arg1;
}
/* 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 (pptr[i+2]->op == oSTSXH)
{
pptr[i+2]->op = oSTSH;
pptr[i+2]->arg2 += pptr[i]->arg2;
deletePcode (i);
nchanges++;
} /* end if */
else if (pptr[i+2]->op == oSTSXB)
{
pptr[i+2]->op = oSTSB;
pptr[i+2]->arg2 += pptr[i]->arg2;
deletePcode (i);
nchanges++;
} /* end if */
else i++;
} /* end if */
else i++;
break;
case oPUSHB :
if (i < nops-2)
{
if (pptr[i+2]->op == oSTSXB)
{
pptr[i+2]->op = oSTSB;
pptr[i+2]->arg2 += pptr[i]->arg2;
deletePcode (i);
nchanges++;
} /* end if */
else i++;
} /* end if */
else i++;
break;
default :
i++;
break;
} /* end switch */
} /* end while */
return (nchanges);
} /* end StoreOptimize */
/**********************************************************************/
+54
View File
@@ -0,0 +1,54 @@
/***************************************************************************
* plopt.h
* External Declarations associated with plopt.c
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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
/***************************************************************************
* Included Files
***************************************************************************/
#include <stdint.h>
/***************************************************************************
* Public Function Prototypes
***************************************************************************/
extern int16_t LoadOptimize ( void );
extern int16_t StoreOptimize ( void );
#endif /* __PLOPT_H */
+301
View File
@@ -0,0 +1,301 @@
/**********************************************************************
* polocal.c
* P-Code Local Optimizer
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include <stdio.h>
#include "keywords.h"
#include "podefs.h"
#include "pinsn16.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 */
int16_t nops = 0; /* No. Valid Pcode Pointers */
int16_t 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)
{
int16_t 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(int16_t delIndex)
{
TRACE(stderr, "[deletePcode]");
pptr[delIndex]->op = oNOP;
pptr[delIndex]->arg1 = 0;
pptr[delIndex]->arg2 = 0;
setupPointer();
}
/**********************************************************************/
void deletePcodePair(int16_t delIndex1, int16_t delIndex2)
{
TRACE(stderr, "[deletePcodePair]");
pptr[delIndex1]->op = oNOP;
pptr[delIndex1]->arg1 = 0;
pptr[delIndex1]->arg2 = 0;
pptr[delIndex2]->op = oNOP;
pptr[delIndex2]->arg1 = 0;
pptr[delIndex2]->arg2 = 0;
setupPointer();
}
/**********************************************************************
* Private Functions
**********************************************************************/
/***********************************************************************/
static void putPCodeFromTable(void)
{
register int16_t i;
TRACE(stderr, "[putPCodeFromTable]");
/* Transfer all buffered P-Codes (except NOPs) to the optimized file */
do
{
if ((ptable[0].op != oNOP) && !(end_out))
{
(void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].op);
if (ptable[0].op & o8)
(void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].arg1);
if (ptable[0].op & o16)
{
(void)poffAddTmpProgByte(myPoffProgHandle,
(ptable[0].arg2 >> 8));
(void)poffAddTmpProgByte(myPoffProgHandle,
(ptable[0].arg2 & 0xff));
}
end_out =(ptable[0].op == oEND);
}
/* Move all P-Codes down one slot */
for (i = 1; i < WINDOW; i++)
{
ptable[i-1].op = ptable[i].op ;
ptable[i-1].arg1 = ptable[i].arg1;
ptable[i-1].arg2 = ptable[i].arg2;
}
/* Then fill the end slot with a new P-Code from the input file */
insn_GetOpCode(myPoffHandle, &ptable[WINDOW-1]);
} while (ptable[0].op == oNOP);
setupPointer();
}
/**********************************************************************/
static void setupPointer(void)
{
register int16_t pindex;
TRACE(stderr, "[setupPointer]");
for (pindex = 0; pindex < WINDOW; pindex++)
pptr[pindex] = (OPTYPE *) NULL;
nops = 0;
for (pindex = 0; pindex < WINDOW; pindex++)
{
switch (ptable[pindex].op)
{
/* 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 int16_t i;
TRACE(stderr, "[intPTable]");
/* Skip over leading pcodes. NOTE: assumes executable begins after
* the first oLABEL pcode
*/
do
{
insn_GetOpCode(myPoffHandle, &ptable[0]);
(void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].op);
if (ptable[0].op & o8)
{
(void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].arg1);
}
if (ptable[0].op & o16)
{
(void)poffAddTmpProgByte(myPoffProgHandle, (ptable[0].arg2 >> 8));
(void)poffAddTmpProgByte(myPoffProgHandle, (ptable[0].arg2 & 0xff));
} /* end if */
}
while ((ptable[0].op != oLABEL) && (ptable[0].op != oEND));
/* Fill the pcode window and setup pointers to working section */
for (i = 0; i < WINDOW; i++)
{
insn_GetOpCode(myPoffHandle, &ptable[i]);
}
setupPointer();
}
/***********************************************************************/
+74
View File
@@ -0,0 +1,74 @@
/***************************************************************************
* polocal.h
* External Declarations associated with polocal.c
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <stdint.h>
#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 (int16_t delIndex);
extern void deletePcodePair (int16_t delIndex1, int16_t delIndex2);
/***************************************************************************
* Global Variables
****************************************************************************/
extern OPTYPE ptable [WINDOW]; /* Pcode Table */
extern OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */
extern int16_t nops; /* No. Valid Pcode Pointers */
extern int16_t end_out; /* 1 = oEND pcode has been output */
#endif /* __PLOCAL_H */
+289
View File
@@ -0,0 +1,289 @@
/**********************************************************************
* popt.c
* P-Code Optimizer Main Logic
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "keywords.h"
#include "podefs.h"
#include "paslib.h"
#include "pofflib.h"
#include "pinsn.h"
#include "popt.h"
#include "psopt.h"
#include "polocal.h"
#include "pfopt.h"
/**********************************************************************
* Private Function Prototypes
**********************************************************************/
static void 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 */
/**********************************************************************
* Global Functions
**********************************************************************/
/***********************************************************************/
int main(int argc, char *argv[], char *envp[])
{
TRACE(stderr, "[main]");
/* Check for existence of filename argument */
if (argc < 2)
{
printf("Filename Required\n");
exit (1);
} /* end if */
/* Read the POFF file into memory */
readPoffFile(argv[1]);
/* Performs pass1 optimization */
pass1();
/* Performs pass2 optimization */
insn_ResetOpCodeRead(poffHandle);
pass2();
/* Create final section offsets and relocation entries */
insn_ResetOpCodeRead(poffHandle);
pass3();
/* Write the POFF file */
writePoffFile(argv[1]);
return 0;
} /* End main */
/**********************************************************************
* Private Functions
**********************************************************************/
/***********************************************************************/
static void readPoffFile(const char *filename)
{
char objname [FNAME_SIZE+1];
FILE *objFile;
uint16_t 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 */
/***********************************************************************/
+52
View File
@@ -0,0 +1,52 @@
/***************************************************************************
* popt.h
* External Declarations associated with popt.c
*
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 Function Prototypes
****************************************************************************/
/***************************************************************************
* Global Variables
****************************************************************************/
#endif /* __POPT_H */
+387
View File
@@ -0,0 +1,387 @@
/**********************************************************************
* psopt.c
* String Stack Optimizaitons
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "keywords.h"
#include "pdefs.h"
#include "pedefs.h"
#include "pinsn16.h"
#include "pxdefs.h"
#include "popt.h"
#include "psopt.h"
/**********************************************************************
* Definitions
**********************************************************************/
#define PBUFFER_SIZE 1024
#define NPBUFFERS 8
/**********************************************************************
* Private Data
**********************************************************************/
static uint8_t *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, (uint8_t)c);
}
else
{
/* PUSHS encountered. Write byte into buffer associated with
* nesting level.
*/
int idx = nbytes_in_pbuffer[dlvl];
uint8_t *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];
uint8_t *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, (uint8_t)c);
}
}
static inline void flushbuf(poffProgHandle_t poffProgHandle)
{
uint16_t 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;
uint8_t *src = pbuffer[slvl];
uint8_t *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 an 8-bit argument */
if ((opcode & o8) != 0)
{
/* Echo the 8-bit argument */
putbuf(inch, poffProgHandle);
inch = poffGetProgByte(poffHandle);
}
/* Check for a 16-bit argument */
if ((opcode & o16) != 0)
{
/* Echo the 16-bit argument */
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)
{
int opcode;
int arg16;
int arg16a;
int arg16b;
/* 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)
{
/* Get the 16-bit argument */
putbuf(inch, poffProgHandle);
arg16a = poffGetProgByte(poffHandle);
putbuf(arg16a, poffProgHandle);
arg16b = poffGetProgByte(poffHandle);
putbuf(arg16b, poffProgHandle);
arg16 = (arg16a << 8) | arg16b;
inch = poffGetProgByte(poffHandle);
/* Is it LIB MKSTK? MKSTKSTR? or MKSTKC? */
if ((arg16 == lbMKSTK) ||
(arg16 == lbMKSTKSTR) ||
(arg16 == 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
{
/* 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 an 8-bit argument */
if ((opcode & o8) != 0)
{
/* Buffer the 8-bit argument */
putbuf(inch, poffProgHandle);
inch = poffGetProgByte(poffHandle);
}
/* Check for a 16-bit argument */
if ((opcode & o16) != 0)
{
/* Buffer the 16-bit argument */
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] = (uint8_t*)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;
}
}
/**********************************************************************/
+54
View File
@@ -0,0 +1,54 @@
/***************************************************************************
* psopt.h
* External Declarations associated with psopt.c
*
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 */
+38
View File
@@ -0,0 +1,38 @@
############################################################################
# insn16/prun/Make.defs
# NuttX runtime makefile fragment
#
# Copyright (C) 2008 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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.
#
############################################################################
PRUN_ASRCS =
PRUN_CSRCS = pload.c pexec.c
+87
View File
@@ -0,0 +1,87 @@
############################################################################
# insn16/prun/Makefile
# Host system makefile
#
# Copyright (C) 2008 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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
#
PRUNDIR = ${shell pwd}
INSNDIR = $(PRUNDIR)/..
PASCAL = $(PRUNDIR)/../..
include $(PASCAL)/Make.config
include $(PASCAL)/Make.defs
INCDIR = $(PASCAL)/include
LIBDIR = $(PASCAL)/lib
BINDIR = $(PASCAL)/bin16
#
# Tools
#
EXTRA_INCLUDES = -I$(INSNDIR)/include
INCLUDES += $(EXTRA_INCLUDES)
CFLAGS += $(EXTRA_INCLUDES)
#
# Objects and targets
#
RUNSRCS = prun.c pdbg.c pload.c pexec.c
RUNOBJS = $(RUNSRCS:.c=.o)
OBJS = $(RUNOBJS)
all: prun
.PHONY: all prun 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
$(BINDIR)/prun: check_libs $(RUNOBJS)
@$(CC) -o $@ $(LDFLAGS) $(RUNOBJS) -linsn -lpoff -lpas -lm
prun: $(BINDIR)/prun
clean:
$(RM) prun *.o core *~
+748
View File
@@ -0,0 +1,748 @@
/**********************************************************************
* pdbg.c
* P-Code Debugger
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
/**********************************************************************
* Included Files
**********************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <ctype.h>
#include "keywords.h"
#include "pdefs.h"
#include "podefs.h"
#include "pinsn16.h"
#include "pxdefs.h"
#include "pedefs.h"
#include "paslib.h"
#include "pinsn.h"
#include "pexec.h"
#include "pdbg.h"
/**********************************************************************
* Pre-processor Definitions
**********************************************************************/
#define TRACE_ARRAY_SIZE 16
#define MAX_BREAK_POINTS 8
#define DISPLAY_STACK_SIZE 16
#define DISPLAY_INST_SIZE 16
/**********************************************************************
* Private Type Definitions
**********************************************************************/
enum command_e
{
eCMD_NONE = 0,
eCMD_RESET,
eCMD_RUN,
eCMD_STEP,
eCMD_NEXT,
eCMD_GO,
eCMD_BS,
eCMD_BC,
eCMD_DP,
eCMD_DT,
eCMD_DS,
eCMD_DI,
eCMD_DB,
eCMD_HELP,
eCMD_QUIT
};
struct trace_s
{
paddr_t pc;
paddr_t sp;
ustack_t tos;
};
typedef struct trace_s trace_t;
/**********************************************************************
* Private Constant Data
**********************************************************************/
/**********************************************************************
* Private Data
**********************************************************************/
static enum command_e g_lastcmd = eCMD_NONE;
static uint32_t g_lastvalue;
/**********************************************************************
* Private Function Prototypes
**********************************************************************/
static void pdbg_showcommands(void);
static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32_t value);
static int32_t pdbg_readdecimal(char *ptr);
static int32_t pdbg_readhex(char *ptr, int32_t defaultvalue);
static void pdbg_programstatus(struct pexec_s *st);
static paddr_t pdbg_printpcode(struct pexec_s *st, paddr_t pc, int16_t nitems);
static paddr_t pdbg_printstack(struct pexec_s *st, paddr_t sp, int16_t nitems);
static void pdbg_printregisters(struct pexec_s *st);
static void pdbg_printtracearray(struct pexec_s *st);
static void pdbg_addbreakpoint(paddr_t pc);
static void pdbg_deletebreakpoint(int16_t bpno);
static void pdbg_printbreakpoints(struct pexec_s *st);
static void pdbg_checkbreakpoint(struct pexec_s *st);
static void pdbg_initdebugger(void);
static void pdbg_debugpcode(struct pexec_s *st);
/**********************************************************************
* Global Variables
**********************************************************************/
/**********************************************************************
* Private Variables
**********************************************************************/
/* Debugging variables */
static trace_t g_tracearray[TRACE_ARRAY_SIZE];
/* Holds execution histor */
static uint16_t g_tracendx;
/* This is the index into the circular g_tracearray */
static uint16_t g_ntracepoints;
/* This is the number of valid enties in g_tracearray */
static paddr_t g_breakpoint[MAX_BREAK_POINTS];
/* Contains address associated with all active */
/* break points. */
static paddr_t g_untilpoint;
/* The 'g_untilpoint' is a temporary breakpoint */
static uint16_t g_nbreakpoints;
/* Number of items in breakPoints[] */
static paddr_t g_displayloc;
/* P-code display location display */
static bool g_bstopexecution;
/* true means to stop program execution */
/* I/O variables */
static char g_inline[LINE_SIZE+1];
/* Command line buffer */
/**********************************************************************
* Public Functions
**********************************************************************/
void dbg_run(struct pexec_s *st)
{
paddr_t pc;
int i;
pdbg_showcommands();
pdbg_initdebugger();
pdbg_programstatus(st);
while (true)
{
printf("CMD: ");
(void) fgets(g_inline, LINE_SIZE, stdin);
switch (toupper(g_inline[0]))
{
case 'R' :
switch (toupper(g_inline[1])) {
case 'E' : /* Reset */
pdbg_execcommand(st, eCMD_RESET, 0);
break;
case 'U' : /* Run */
pdbg_execcommand(st, eCMD_RUN, 0);
break;
default :
printf("Unrecognized Command\n");
pdbg_execcommand(st, eCMD_HELP, 0);
break;
} /* end switch */
break;
case 'S' : /* Single Step (into) */
pdbg_execcommand(st, eCMD_STEP, 0);
break;
case 'N' : /* Single Step (over) */
pdbg_execcommand(st, eCMD_NEXT, 0);
break;
case 'G' : /* Go */
pdbg_execcommand(st, eCMD_GO, 0);
break;
case 'B' :
switch (toupper(g_inline[1])) {
case 'S' : /* Set Breakpoint */
pc = pdbg_readhex(&g_inline[2], st->pc);
pdbg_execcommand(st, eCMD_BS, pc);
break;
case 'C' : /* Clear Breakpoint */
i = pdbg_readdecimal(&g_inline[2]);
pdbg_execcommand(st, eCMD_BC, i);
break;
default :
printf("Unrecognized Command\n");
pdbg_execcommand(st, eCMD_HELP, 0);
break;
} /* end switch */
break;
case 'D' :
switch (toupper(g_inline[1])) {
case 'P' : /* Display Program Status */
pdbg_execcommand(st, eCMD_DP, 0);
break;
case 'T' : /* Display Program Trace */
pdbg_execcommand(st, eCMD_DT, 0);
break;
case 'S' : /* Display Stack */
pc = pdbg_readhex(&g_inline[2], st->sp);
pdbg_execcommand(st, eCMD_DS, pc);
break;
case 'I' : /* Display Instructions */
pc = pdbg_readhex(&g_inline[2], st->pc);
pdbg_execcommand(st, eCMD_DI, pc);
break;
case 'B' : /* Display Breakpoints */
pdbg_execcommand(st, eCMD_DB, pc);
break;
default :
printf("Unrecognized Command\n");
pdbg_execcommand(st, eCMD_HELP, 0);
break;
} /* end switch */
break;
case 'Q' : /* Quit */
pdbg_execcommand(st, eCMD_QUIT, pc);
break;
case 'H' : /* Help */
case '?' :
pdbg_execcommand(st, eCMD_HELP, 0);
break;
case '\0' : /* Repeat last command */
case '\n' : /* Repeat last command */
pdbg_execcommand(st, g_lastcmd, g_lastvalue);
break;
default :
printf("Unrecognized Command\n");
pdbg_execcommand(st, eCMD_HELP, 0);
break;
} /* end switch */
} /* end while */
} /* end pdbg_debugpcodeProgram */
/**********************************************************************
* Private Functions
**********************************************************************/
/* Show command characters */
static void pdbg_showcommands(void)
{
printf("Commands:\n");
printf(" RE[set] - Reset\n");
printf(" RU[n] - Run\n");
printf(" S[tep] - Single Step (Into)\n");
printf(" N[ext] - Single Step (Over)\n");
printf(" G[o] - Go\n");
printf(" BS xxxx - Set Breakpoint\n");
printf(" BC n - Clear Breakpoint\n");
printf(" DP - Display Program Status\n");
printf(" DT - Display Program Trace\n");
printf(" DS [xxxx] - Display Stack\n");
printf(" DI [xxxx] - Display Instructions\n");
printf(" DB - Display Breakpoints\n");
printf(" H or ? - Shows this list\n");
printf(" Q[uit] - Quit\n");
} /* end pdbg_showcommands */
/***********************************************************************/
static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32_t value)
{
/* Save the command to resuse if the user enters nothing */
g_lastcmd = cmd;
g_lastvalue = value;
switch (cmd)
{
case eCMD_NONE: /* Do nothing */
break;
case eCMD_RESET: /* Reset */
pexec_reset(st);
pdbg_initdebugger();
pdbg_programstatus(st);
g_lastcmd = eCMD_NONE;
break;
case eCMD_RUN: /* Run */
pexec_reset(st);
pdbg_initdebugger();
pdbg_debugpcode(st);
pdbg_programstatus(st);
break;
case eCMD_STEP: /* Single Step (into)*/
g_bstopexecution = true;
pdbg_debugpcode(st);
pdbg_programstatus(st);
break;
case eCMD_NEXT: /* Single Step (over) */
if (st->ispace[st->pc] == oPCAL)
{
g_bstopexecution = false;
g_untilpoint = st->pc + 4;
}
else
{
g_bstopexecution = true;
}
pdbg_debugpcode(st);
g_untilpoint = 0;
pdbg_programstatus(st);
break;
case eCMD_GO: /* Go */
g_bstopexecution = false;
pdbg_debugpcode(st);
pdbg_programstatus(st);
break;
case eCMD_BS: /* Set Breakpoint */
if (g_nbreakpoints >= MAX_BREAK_POINTS)
{
printf("Too many breakpoints\n");
g_lastcmd = eCMD_NONE;
}
else if (value >= st->maxpc)
{
printf("Invalid address for breakpoint\n");
g_lastcmd = eCMD_NONE;
}
else
{
pdbg_addbreakpoint(value);
pdbg_printbreakpoints(st);
} /* end else */
break;
case eCMD_BC: /* Clear Breakpoint */
if ((value >= 1) && (value <= g_nbreakpoints))
{
pdbg_deletebreakpoint(value);
}
else
{
printf("Invalid breakpoint number\n");
g_lastcmd = eCMD_NONE;
}
pdbg_printbreakpoints(st);
break;
case eCMD_DP: /* Display Program Status */
pdbg_programstatus(st);
break;
case eCMD_DT: /* Display Program Trace */
pdbg_printtracearray(st);
break;
case eCMD_DS: /* Display Stack */
if (value > st->sp)
{
printf("Invalid stack address\n");
g_lastcmd = eCMD_NONE;
}
else
{
g_lastvalue = pdbg_printstack(st, value, DISPLAY_STACK_SIZE);
} /* end else */
break;
case eCMD_DI: /* Display Instructions */
if (value >= st->maxpc)
{
printf("Invalid instruction address\n");
g_lastcmd = eCMD_NONE;
}
else
{
g_lastvalue = pdbg_printpcode(st, value, DISPLAY_INST_SIZE);
} /* end else */
break;
case eCMD_DB: /* Display Breakpoints */
pdbg_printbreakpoints(st);
break;
case eCMD_QUIT: /* Quit */
printf("Goodbye\n");
exit(0);
break;
case eCMD_HELP: /* Help */
default: /* Internal error */
pdbg_showcommands();
g_lastcmd = eCMD_NONE;
break;
} /* end switch */
} /* end pdbg_execcommand */
/***********************************************************************/
/* Read a decimal value from the input string */
static int32_t pdbg_readdecimal(char *ptr)
{
int32_t decimal = 0;
while (!isspace(*ptr)) ptr++;
while (isspace(*ptr)) ptr++;
for (; ((*ptr >= '0') && (*ptr <= '9')); ptr++)
decimal = 10*decimal + (int32_t)*ptr - (int32_t)'0';
return decimal;
} /* end pdbg_readdecimal */
/***********************************************************************/
/* Read a hexadecimal value from the input string */
static int32_t pdbg_readhex(char *ptr, int32_t defaultvalue)
{
char c;
int32_t hex = 0;
bool found = false;
while (!isspace(*ptr)) ptr++;
while (isspace(*ptr)) ptr++;
while (true) {
c = toupper(*ptr);
if ((c >= '0') && (c <= '9')) {
hex = ((hex << 4) | ((int32_t)c - (int32_t)'0'));
found = true;
} /* end if */
else if ((c >= 'A') && (c <= 'F')) {
hex = ((hex << 4) | ((int32_t)c - (int32_t)'A' + 10));
found = true;
} /* end else if */
else {
if (found)
return hex;
else
return defaultvalue;
} /* end else */
ptr++;
} /* end while */
} /* end pdbg_readhex */
/***********************************************************************/
/* Print the disassembled P-Code at PC */
static void pdbg_programstatus(struct pexec_s *st)
{
(void)pdbg_printpcode(st, st->pc, 1);
(void)pdbg_printstack(st, st->sp, 2);
pdbg_printregisters(st);
} /* end pdbg_programstatus */
/***********************************************************************/
/* Print the disassembled P-Code at PC */
static paddr_t pdbg_printpcode(struct pexec_s *st, paddr_t pc, int16_t nitems)
{
OPTYPE op;
paddr_t opsize;
uint8_t *address;
for (; ((pc < st->maxpc) && (nitems > 0)); nitems--)
{
address = &st->ispace[pc];
op.op = *address++;
op.arg1 = 0;
op.arg2 = 0;
opsize = 1;
printf("PC:%04x %02x", pc, op.op);
if ((op.op & o8) != 0)
{
op.arg1 = *address++;
printf("%02x", op.arg1);
opsize++;
} /* end if */
else
printf("..");
if ((op.op & o16) != 0)
{
op.arg2 = ((*address++) << 8);
op.arg2 |= *address++;
printf("%04x", op.arg2);
opsize += 2;
} /* end if */
else
printf("....");
/* The disassemble it to stdout */
printf(" ");
insn_DisassemblePCode(stdout, &op);
/* Get the address of the next P-Code */
pc += opsize;
} /* end for */
return pc;
} /* end pdbg_printpcode */
/***********************************************************************/
/* Print the stack value at SP */
static paddr_t pdbg_printstack(struct pexec_s *st, paddr_t sp, int16_t nitems)
{
int32_t isp;
if ((st->sp < st->stacksize) && (sp <= st->sp))
{
isp = BTOISTACK(sp);
printf("SP:%04x %04x\n", sp, st->dstack.i[isp]);
for (isp--, sp -= BPERI, nitems--;
((isp >= 0) && (nitems > 0));
isp--, sp -= BPERI, nitems--)
printf(" %04x %04x\n", sp, st->dstack.i[isp] & 0xffff);
} /* end if */
else
{
printf("SP:%04x BAD\n", sp);
} /* end else */
return sp;
} /* end pdbg_printstack */
/***********************************************************************/
/* Print the base register */
static void pdbg_printregisters(struct pexec_s *st)
{
if (st->fp <= st->sp)
printf("FP:%04x ", st->fp);
printf("CSP:%04x\n", st->csp);
} /* end pdbg_printregisters */
/***********************************************************************/
/* Print the g_tracearray */
static void pdbg_printtracearray(struct pexec_s *st)
{
int nprinted;
int index;
index = g_tracendx + TRACE_ARRAY_SIZE - g_ntracepoints;
if (index >= TRACE_ARRAY_SIZE)
index -= TRACE_ARRAY_SIZE;
for (nprinted = 0; nprinted < g_ntracepoints; nprinted++) {
printf("SP:%04x %04x ",
g_tracearray[ index ].sp, g_tracearray[ index ].tos);
/* Print the instruction executed at this traced address */
(void)pdbg_printpcode(st, g_tracearray[ index ].pc, 1);
/* Index to the next trace entry */
if (++index >= TRACE_ARRAY_SIZE)
index = 0;
} /* end for */
} /* end pdbg_printtracearray */
/***********************************************************************/
/* Add a breakpoint to the breakpoint array */
static void pdbg_addbreakpoint(paddr_t pc)
{
int i;
/* Is there room for another breakpoint? */
if (g_nbreakpoints < MAX_BREAK_POINTS)
{
/* Yes..Check if the breakpoint already exists */
for (i = 0; i < g_nbreakpoints; i++)
{
if (g_breakpoint[i] == pc)
{
/* It is already set. Return without doing anything */
return;
}
}
/* The breakpoint is not already set -- set it */
g_breakpoint[g_nbreakpoints++] = pc;
} /* end if */
} /* end pdbg_addbreakpoint */
/***********************************************************************/
/* Remove a breakpoint from the breakpoint array */
static void pdbg_deletebreakpoint(int16_t bpno)
{
if ((bpno >= 1) && (bpno <= g_nbreakpoints)) {
for (; (bpno < g_nbreakpoints); bpno++)
g_breakpoint[bpno-1] = g_breakpoint[bpno];
g_nbreakpoints--;
} /* end if */
} /* end pdbg_deletebreakpoint */
/***********************************************************************/
/* Print the breakpoint array */
static void pdbg_printbreakpoints(struct pexec_s *st)
{
int i;
printf("BP:# Address P-Code\n");
for (i = 0; i < g_nbreakpoints; i++)
{
printf("BP:%d ", (i+1));
(void)pdbg_printpcode(st, g_breakpoint[i], 1);
} /* end for */
} /* end pdbg_printbreakpoints */
/***********************************************************************/
/* Check if a breakpoint is set at the current value of program counter.
* If so, print the instruction and stop execution. */
static void pdbg_checkbreakpoint(struct pexec_s *st)
{
uint16_t bpIndex;
/* Check for a user breakpoint */
for (bpIndex = 0;
((bpIndex < g_nbreakpoints) && (!g_bstopexecution));
bpIndex++)
{
if (g_breakpoint[bpIndex] == st->pc)
{
printf("Breakpoint #%d -- Execution Stopped\n", (bpIndex+1));
g_bstopexecution = true;
return;
} /* end if */
} /* end for */
} /* end pdbg_checkbreakpoint */
/***********************************************************************/
/* Initialize Debugger variables */
static void pdbg_initdebugger(void)
{
g_bstopexecution = false;
g_displayloc = 0;
g_tracendx = 0;
g_ntracepoints = 0;
}
/***********************************************************************/
/* This function executes the P-Code program until a stopping condition
* is encountered. */
static void pdbg_debugpcode(struct pexec_s *st)
{
uint16_t errno;
do {
/* Trace the next instruction execution */
g_tracearray[g_tracendx].pc = st->pc;
g_tracearray[g_tracendx].sp = st->sp;
if (st->sp < st->stacksize)
g_tracearray[g_tracendx].tos = st->dstack.i[BTOISTACK(st->sp)];
else
g_tracearray[g_tracendx].tos = 0;
if (++g_tracendx >= TRACE_ARRAY_SIZE)
g_tracendx = 0;
if (g_ntracepoints < TRACE_ARRAY_SIZE)
g_ntracepoints++;
/* Execute the instruction */
errno = pexec(st);
/* Check for exceptional stopping conditions */
if (errno != eNOERROR)
{
if (errno == eEXIT)
printf("Normal Termination\n");
else
printf("Runtime error 0x%02x -- Execution Stopped\n", errno);
g_bstopexecution = true;
} /* end if */
/* Check for normal stopping conditions */
if (!g_bstopexecution)
{
/* Check for attempt to execute code outside of legal range */
if (st->pc >= st->maxpc)
g_bstopexecution = true;
/* Check for a temporary breakpoint */
else if ((g_untilpoint > 0) && (g_untilpoint == st->pc))
g_bstopexecution = true;
/* Check if there is a breakpoint at the next instruction */
else if (g_nbreakpoints > 0)
pdbg_checkbreakpoint(st);
}
} while (!g_bstopexecution);
} /* end pdbg_debugpcode */
File diff suppressed because it is too large Load Diff
+176
View File
@@ -0,0 +1,176 @@
/****************************************************************************
* pload.c
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "keywords.h"
#include "pedefs.h"
#include "pofflib.h"
#include "perr.h"
#include "pexec.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Definitions
****************************************************************************/
/****************************************************************************
* Private Constant Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Global Variables
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
FAR struct pexec_s *pload(const char *filename, paddr_t varsize, paddr_t strsize)
{
struct pexec_attr_s attr;
struct pexec_s *st;
poffHandle_t phandle;
FILE *exe;
uint16_t err;
uint8_t ftype;
uint8_t farch;
/* Create a handle to contain the executable data */
phandle = poffCreateHandle();
if (phandle == NULL) fatal(eNOMEMORY);
/* Open the executable file */
if (!(exe = fopen(filename, "rb")))
{
dbg("ERROR: Error opening '%s': %d\n", filename, errno);
goto errout_with_handle;
}
/* Load the POFF file into memory */
err = poffReadFile(phandle, exe);
if (err != eNOERROR)
{
dbg("ERROR: Could not read %s: %d\n", filename, err);
goto errout_with_file;
}
/* Verify that the file is a pascal executable */
ftype = poffGetFileType(phandle);
if (ftype != FHT_EXEC)
{
dbg("ERROR: File is not a pascal executable: %d\n", ftype);
goto errout_with_file;
}
farch = poffGetArchitecture(phandle);
if (farch != FHA_PCODE_INSN16)
{
dbg("ERROR: File is not 16-bit pcode: %d\n", farch);
goto errout_with_file;
}
/* Initialize the attribute structure */
attr.varsize = varsize;
attr.strsize = strsize;
/* Extract the program entry point from the pascal executable */
attr.entry = poffGetEntryPoint(phandle);
/* Close the POFF file */
(void)fclose(exe);
/* Extract the program data from the POFF image */
attr.maxpc = poffExtractProgramData(phandle, &attr.ispace);
/* Extract the read-only data from the POFF image */
attr.rosize = poffExtractRoData(phandle, &attr.rodata);
/* Destroy the POFF image */
poffDestroyHandle(phandle);
/* Initialize the p-code interpreter */
st = pexec_init(&attr);
if (!st && attr.ispace)
{
/* Initialization failed, discard the allocated I-Space */
free(st->ispace);
}
/* Discard the allocated RO data in any event */
if (attr.rodata)
{
free(attr.rodata);
}
return st;
errout_with_file:
(void)fclose(exe);
errout_with_handle:
poffDestroyHandle(phandle);
return NULL;
}
+278
View File
@@ -0,0 +1,278 @@
/****************************************************************************
* prun.c
*
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "keywords.h"
#include "pdefs.h"
#include "pinsn16.h"
#include "pxdefs.h"
#include "pedefs.h"
#include "paslib.h"
#include "perr.h"
#include "pexec.h"
#include "pdbg.h"
/****************************************************************************
* Definitions
****************************************************************************/
#define MIN_STACK_SIZE 1024
#define DEFAULT_STACK_SIZE 4096
#define DEFAULT_STKSTR_SIZE 0
/****************************************************************************
* Private Type Definitions
****************************************************************************/
/****************************************************************************
* Private Constant Data
****************************************************************************/
static const struct option long_options[] =
{
{"stack", 1, NULL, 's'},
{"string", 1, NULL, 't'},
{"debug", 0, NULL, 'd'},
{"help", 0, NULL, 'h'},
{NULL, 0, NULL, 0}
};
/****************************************************************************
* Private Data
****************************************************************************/
static const char *g_pofffilename;
static int32_t g_varstacksize = DEFAULT_STACK_SIZE;
static int32_t g_strstacksize = DEFAULT_STKSTR_SIZE;
static int g_debug = 0;
/****************************************************************************
* Global Variables
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: prun_showusage
****************************************************************************/
static void prun_showusage(const char *progname)
{
fprintf(stderr, "Usage:\n");
fprintf(stderr, " %s [options] <program-filename>\n",
progname);
fprintf(stderr, "options:\n");
fprintf(stderr, " -s <stack-size>\n");
fprintf(stderr, " --stack <stack-size>\n");
fprintf(stderr, " Memory in bytes to allocate for the pascal program\n");
fprintf(stderr, " stack in bytes (minimum is %d; default is %d bytes)\n",
MIN_STACK_SIZE, DEFAULT_STACK_SIZE);
fprintf(stderr, " -t <stack-size>\n");
fprintf(stderr, " --string <string-storage-size>\n");
fprintf(stderr, " Memory in bytes to allocate for the pascal program\n");
fprintf(stderr, " string storage in bytes (default is %d bytes)\n",
DEFAULT_STKSTR_SIZE);
fprintf(stderr, " -d\n");
fprintf(stderr, " --debug\n");
fprintf(stderr, " Enable PCode program debugger\n");
fprintf(stderr, " -h\n");
fprintf(stderr, " --help\n");
fprintf(stderr, " Shows this message\n");
exit(1);
}
/****************************************************************************
* Name: prun_parseargs
****************************************************************************/
static void prun_parseargs(int argc, char **argv)
{
int option_index;
int size;
int c;
/* Check for existence of filename argument */
if (argc < 2)
{
fprintf(stderr, "ERROR: Filename required\n");
prun_showusage(argv[0]);
} /* end if */
/* Parse the command line options */
do
{
c = getopt_long (argc, argv, "t:s:dh",
long_options, &option_index);
if (c != -1)
{
switch (c)
{
case 's' :
size = atoi(optarg);
if (size < MIN_STACK_SIZE)
{
fprintf(stderr, "ERROR: Invalid stack size\n");
prun_showusage(argv[0]);
}
g_varstacksize = (size + 3) & ~3;
break;
case 't' :
size = atoi(optarg);
if (size < 0)
{
fprintf(stderr, "ERROR: Invalid string storage size\n");
prun_showusage(argv[0]);
}
g_strstacksize = ((size + 3) & ~3);
break;
case 'd' :
g_debug++;
break;
case 'h' :
prun_showusage(argv[0]);
break;
default:
/* Shouldn't happen */
fprintf(stderr, "ERROR: Unrecognized option\n");
prun_showusage(argv[0]);
}
}
}
while (c != -1);
if (optind != argc-1)
{
fprintf(stderr, "ERROR: Only one filename permitted on command line\n");
prun_showusage(argv[0]);
}
/* Get the name of the p-code file(s) from the last argument(s) */
g_pofffilename = argv[argc-1];
}
/****************************************************************************
* Name: prun
*
* Description:
* This function executes the P-Code program until a stopping condition
* is encountered.
*
****************************************************************************/
static void prun(struct pexec_s *st)
{
int errcode;
for (;;)
{
/* Execute the instruction; Check for exceptional conditions */
errcode = pexec(st);
if (errcode != eNOERROR) break;
}
if (errcode != eEXIT)
{
printf("Runtime error 0x%02x -- Execution Stopped\n", errcode);
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: main
****************************************************************************/
int main(int argc, char *argv[], char *envp[])
{
struct pexec_s *st;
char fileName[FNAME_SIZE+1]; /* Object file name */
/* Parse the command line arguments */
prun_parseargs(argc, argv);
/* Load the POFF files specified on the command line */
/* Use .o or command line extension, if supplied */
(void)extension(g_pofffilename, "o", fileName, 0);
/* Load the POFF file */
st = pload(fileName, g_varstacksize, g_strstacksize);
if (!st)
{
fprintf(stderr, "ERROR: Could not load %s\n", fileName);
exit(1);
} /* end if */
printf("%s Loaded\n", fileName);
/* And start program execution in the specified mode */
if (g_debug)
dbg_run(st);
else
prun(st);
/* Clean up resources used by the interpreter */
pexec_release(st);
return 0;
} /* end main */