mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-24 02:03:34 +08:00
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:
@@ -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.
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 *~
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -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 */
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -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 *~
|
||||
@@ -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 */
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -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 *~
|
||||
@@ -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 */
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
@@ -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 */
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
/***********************************************************************/
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
@@ -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 *~
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
Reference in New Issue
Block a user