+2002-05-10 Scott Dattal <scott@dattalo.com>
+ * src/pic/*: Added support for multiplication. Fixed many,many bugs.
+
2002-04-22 Michael Hope <michaelh@vroom>
* device/lib/z80/printf.c: Changed emitter to volatile to work around a pcall bug.
-for ac_prog in mawk gawk nawk awk
+for ac_prog in gawk mawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
fi
fi
+for ac_declaration in \
+ ''\
+ '#include <stdlib.h>' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat > conftest.$ac_ext <<EOF
+#line 1021 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+$ac_declaration
+int main() {
+exit (42);
+; return 0; }
+EOF
+if { (eval echo configure:1029: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ continue
+fi
+rm -f conftest*
+ cat > conftest.$ac_ext <<EOF
+#line 1039 "configure"
+#include "confdefs.h"
+$ac_declaration
+int main() {
+exit (42);
+; return 0; }
+EOF
+if { (eval echo configure:1046: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
+fi
+
+
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1012: checking how to run the C preprocessor" >&5
+echo "configure:1063: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1027 "configure"
+#line 1078 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1033: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1084: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1044 "configure"
+#line 1095 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1050: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1101: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1061 "configure"
+#line 1112 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1067: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1118: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1122: checking for a BSD compatible install" >&5
+echo "configure:1173: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1177: checking for $ac_word" >&5
+echo "configure:1228: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "flex", so it can be a program name with args.
set dummy flex; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1207: checking for $ac_word" >&5
+echo "configure:1258: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
*) ac_lib=l ;;
esac
echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
-echo "configure:1241: checking for yywrap in -l$ac_lib" >&5
+echo "configure:1292: checking for yywrap in -l$ac_lib" >&5
ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-l$ac_lib $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1249 "configure"
+#line 1300 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
yywrap()
; return 0; }
EOF
-if { (eval echo configure:1260: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1311: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
# Extract the first word of "bison", so it can be a program name with args.
set dummy bison; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1285: checking for $ac_word" >&5
+echo "configure:1336: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "autoconf", so it can be a program name with args.
set dummy autoconf; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1315: checking for $ac_word" >&5
+echo "configure:1366: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AUTOCONF'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "strip", so it can be a program name with args.
set dummy strip; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1345: checking for $ac_word" >&5
+echo "configure:1396: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "as", so it can be a program name with args.
set dummy as; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1375: checking for $ac_word" >&5
+echo "configure:1426: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "cp", so it can be a program name with args.
set dummy cp; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1405: checking for $ac_word" >&5
+echo "configure:1456: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Checking for header files.
# ===========================================================================
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1455: checking for ANSI C header files" >&5
+echo "configure:1506: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1460 "configure"
+#line 1511 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1468: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1519: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1485 "configure"
+#line 1536 "configure"
#include "confdefs.h"
#include <string.h>
EOF
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1503 "configure"
+#line 1554 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
:
else
cat > conftest.$ac_ext <<EOF
-#line 1524 "configure"
+#line 1575 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
exit (0); }
EOF
-if { (eval echo configure:1535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1586: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1562: checking for $ac_hdr" >&5
+echo "configure:1613: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1567 "configure"
+#line 1618 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1572: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1623: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1602: checking for $ac_hdr" >&5
+echo "configure:1653: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1607 "configure"
+#line 1658 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1612: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1663: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1642: checking for $ac_hdr" >&5
+echo "configure:1693: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1647 "configure"
+#line 1698 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1652: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1703: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1682: checking for $ac_hdr" >&5
+echo "configure:1733: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1687 "configure"
+#line 1738 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1692: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1743: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1722: checking for $ac_hdr" >&5
+echo "configure:1773: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1727 "configure"
+#line 1778 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1732: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1783: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1762: checking for $ac_hdr" >&5
+echo "configure:1813: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1767 "configure"
+#line 1818 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1772: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1823: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1802: checking for $ac_hdr" >&5
+echo "configure:1853: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1807 "configure"
+#line 1858 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1812: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1863: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:1843: checking for $ac_hdr that defines DIR" >&5
+echo "configure:1894: checking for $ac_hdr that defines DIR" >&5
if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1848 "configure"
+#line 1899 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_hdr>
DIR *dirp = 0;
; return 0; }
EOF
-if { (eval echo configure:1856: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1907: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_header_dirent_$ac_safe=yes"
else
# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
if test $ac_header_dirent = dirent.h; then
echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:1881: checking for opendir in -ldir" >&5
+echo "configure:1932: checking for opendir in -ldir" >&5
ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-ldir $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1889 "configure"
+#line 1940 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
opendir()
; return 0; }
EOF
-if { (eval echo configure:1900: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
else
echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:1922: checking for opendir in -lx" >&5
+echo "configure:1973: checking for opendir in -lx" >&5
ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lx $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1930 "configure"
+#line 1981 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
opendir()
; return 0; }
EOF
-if { (eval echo configure:1941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1992: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
# This must be after CPP
echo $ac_n "checking which header file defines FD_ macros""... $ac_c" 1>&6
-echo "configure:1967: checking which header file defines FD_ macros" >&5
+echo "configure:2018: checking which header file defines FD_ macros" >&5
if eval "test \"`echo '$''{'s51_cv_fd'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
sdcc_cv_fd="unknown"
cat > conftest.$ac_ext <<EOF
-#line 1973 "configure"
+#line 2024 "configure"
#include "confdefs.h"
#include <sys/time.h>
rm -f conftest*
cat > conftest.$ac_ext <<EOF
-#line 1989 "configure"
+#line 2040 "configure"
#include "confdefs.h"
#include <sys/types.h>
rm -f conftest*
cat > conftest.$ac_ext <<EOF
-#line 2005 "configure"
+#line 2056 "configure"
#include "confdefs.h"
#include <sys/select.h>
for ac_func in strlen strcpy strcat strstr strcmp strerror strtok strdup
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2085: checking for $ac_func" >&5
+echo "configure:2136: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2090 "configure"
+#line 2141 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2164: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
for ac_func in strchr memcpy
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2140: checking for $ac_func" >&5
+echo "configure:2191: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2145 "configure"
+#line 2196 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2168: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
for ac_func in fgets
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2195: checking for $ac_func" >&5
+echo "configure:2246: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2200 "configure"
+#line 2251 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
for ac_func in yylex
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2250: checking for $ac_func" >&5
+echo "configure:2301: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2255 "configure"
+#line 2306 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
; return 0; }
EOF
-if { (eval echo configure:2278: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2329: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
# check if -lsocket && -lxnet is required to compile socket stuff
echo $ac_n "checking for library containing socket""... $ac_c" 1>&6
-echo "configure:2306: checking for library containing socket" >&5
+echo "configure:2357: checking for library containing socket" >&5
if eval "test \"`echo '$''{'ac_cv_search_socket'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_func_search_save_LIBS="$LIBS"
ac_cv_search_socket="no"
cat > conftest.$ac_ext <<EOF
-#line 2313 "configure"
+#line 2364 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
socket()
; return 0; }
EOF
-if { (eval echo configure:2324: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_socket="none required"
else
test "$ac_cv_search_socket" = "no" && for i in socket; do
LIBS="-l$i $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2335 "configure"
+#line 2386 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
socket()
; return 0; }
EOF
-if { (eval echo configure:2346: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_socket="-l$i"
break
fi
echo $ac_n "checking for library containing inet_addr""... $ac_c" 1>&6
-echo "configure:2368: checking for library containing inet_addr" >&5
+echo "configure:2419: checking for library containing inet_addr" >&5
if eval "test \"`echo '$''{'ac_cv_search_inet_addr'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_func_search_save_LIBS="$LIBS"
ac_cv_search_inet_addr="no"
cat > conftest.$ac_ext <<EOF
-#line 2375 "configure"
+#line 2426 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
inet_addr()
; return 0; }
EOF
-if { (eval echo configure:2386: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2437: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_inet_addr="none required"
else
test "$ac_cv_search_inet_addr" = "no" && for i in nsl xnet; do
LIBS="-l$i $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2397 "configure"
+#line 2448 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
inet_addr()
; return 0; }
EOF
-if { (eval echo configure:2408: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_inet_addr="-l$i"
break
# Checking characteristics of compilers and other programs
# --------------------------------------------------------
echo $ac_n "checking whether preprocessor accepts -MM or -M""... $ac_c" 1>&6
-echo "configure:2442: checking whether preprocessor accepts -MM or -M" >&5
+echo "configure:2493: checking whether preprocessor accepts -MM or -M" >&5
if eval "test \"`echo '$''{'sdcc_cv_MM'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# This is the first time when CFLAGS are set/modified!!
echo $ac_n "checking whether $CC accepts -ggdb""... $ac_c" 1>&6
-echo "configure:2464: checking whether $CC accepts -ggdb" >&5
+echo "configure:2515: checking whether $CC accepts -ggdb" >&5
if eval "test \"`echo '$''{'sdcc_cv_CCggdb'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo $ac_n "checking whether $CC accepts -pipe""... $ac_c" 1>&6
-echo "configure:2489: checking whether $CC accepts -pipe" >&5
+echo "configure:2540: checking whether $CC accepts -pipe" >&5
if eval "test \"`echo '$''{'sdcc_cv_CCpipe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Checks for typedefs, structures, and compiler characteristics.
# ===========================================================================
echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:2516: checking return type of signal handlers" >&5
+echo "configure:2567: checking return type of signal handlers" >&5
if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2521 "configure"
+#line 2572 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
int i;
; return 0; }
EOF
-if { (eval echo configure:2538: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2589: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_type_signal=void
else
if test "$enable_libgc" = "yes"; then
echo $ac_n "checking for GC_malloc in -lgc""... $ac_c" 1>&6
-echo "configure:2827: checking for GC_malloc in -lgc" >&5
+echo "configure:2878: checking for GC_malloc in -lgc" >&5
ac_lib_var=`echo gc'_'GC_malloc | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lgc $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2835 "configure"
+#line 2886 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
GC_malloc()
; return 0; }
EOF
-if { (eval echo configure:2846: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2897: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
exit (1);
}
+/* Override the default processor with the one specified
+ * on the command line */
+static void
+_setProcessor (char *_processor)
+{
+ port->processor = _processor;
+ fprintf(stderr,"Processor: %s\n",_processor);
+}
+
static void
_validatePorts (void)
{
port = _ports[0];
}
+/* search through the command line options for the processor */
+static void
+_findProcessor (int argc, char **argv)
+{
+ while (argc--)
+ {
+ if (!strncmp (*argv, "-p", 2))
+ {
+ _setProcessor (*argv + 2);
+ return;
+ }
+ argv++;
+ }
+
+ /* no error if processor was not specified. */
+}
+
/*-----------------------------------------------------------------*/
/* printVersionInfo - prints the version info */
/*-----------------------------------------------------------------*/
werror (W_UNSUPPORTED_MODEL, sz, port->target);
}
-static void
-_setProcessor (char *_processor)
-{
- port->processor = _processor;
- fprintf(stderr,"Processor: %s\n",_processor);
-}
-
/** Gets the string argument to this option. If the option is '--opt'
then for input of '--optxyz' or '--opt xyz' returns xyz.
*/
break;
case 'm':
- /* Used to select the port */
- _setPort (argv[i] + 2);
+ /* Used to select the port. But this has already been done. */
break;
case 'p':
- /* Used to select the processor in port */
- _setProcessor (getStringArg("-p", argv, &i, argc));
+ /* Used to select the processor in port. But this has
+ * already been done. */
break;
case 'c':
exit (1);
}
+ /* Before parsing the command line options, do a
+ * search for the port and processor and initialize
+ * them if they're found. (We can't gurantee that these
+ * will be the first options specified).
+ */
+
_findPort (argc, argv);
+
#ifdef JAMIN_DS390
if (strcmp(port->target, "mcs51") == 0) {
printf("DS390 jammed in A\n");
ds390_jammed = 1;
}
#endif
+
+ _findProcessor (argc, argv);
+
/* Initalise the port. */
if (port->init)
port->init ();
};
static int num_of_supported_PICS = sizeof(Pics)/sizeof(PIC_device);
-static int default_pic = 0;
+
#define DEFAULT_PIC "f877"
static PIC_device *pic=NULL;
do {
for(i=r->start_address; i<= r->end_address; i++) {
- if(i <= pic->max_address) {
+ if(i <= pic->maxRAMaddress) {
finalMapping[i | alias].isValid = 1;
finalMapping[i | alias].alias = r->alias;
finalMapping[i | alias].bank = r->bank;
/* First, find the maximum address */
r = pPic->ram;
- pPic->max_address = 0;
+ pPic->maxRAMaddress = 0;
do {
- if((r->end_address | r->alias) > pPic->max_address)
- pPic->max_address = r->end_address | r->alias;
+ if((r->end_address | r->alias) > pPic->maxRAMaddress)
+ pPic->maxRAMaddress = r->end_address | r->alias;
r++;
- finalMapping = Safe_calloc(1+pPic->max_address, sizeof(AssignedMemory));
+ finalMapping = Safe_calloc(1+pPic->maxRAMaddress, sizeof(AssignedMemory));
/* Now initialize the finalMapping array */
- for(i=0; i<=pPic->max_address; i++) {
+ for(i=0; i<=pPic->maxRAMaddress; i++) {
finalMapping[i].reg = NULL;
finalMapping[i].isValid = 0;
}
{
int i;
- for(i=0; i<=pic->max_address; i++) {
+ for(i=0; i<=pic->maxRAMaddress; i++) {
//fprintf(stdout , "addr 0x%02x is %s\n", i, ((finalMapping[i].isValid) ? "valid":"invalid"));
if(finalMapping[i].isValid) {
addr++;
- } while(addr <= pic->max_address);
+ } while(addr <= pic->maxRAMaddress);
}
if(list_alias)
list_alias = sizeof(Pics[0].name) / sizeof(Pics[0].name[0]);
- fprintf(stderr,"list_alias size = %d\n",list_alias);
/* decrement the column number if it's greater than zero */
ncols = (ncols > 1) ? ncols-1 : 4;
/*-----------------------------------------------------------------*
*
*-----------------------------------------------------------------*/
-void init_pic(void)
+void init_pic(char *pic_type)
{
- pic = find_device(DEFAULT_PIC);
+ pic = find_device(pic_type);
if(!pic) {
- fprintf(stderr, "%s was not found.\nValid devices are:\n",DEFAULT_PIC);
+ if(pic_type)
+ fprintf(stderr, "'%s' was not found.\n", pic_type);
+ else
+ fprintf(stderr, "No processor has been specified (use -pPROCESSOR_NAME)\n");
+
+ fprintf(stderr,"Valid devices are:\n");
+
list_valid_pics(4,0);
exit(1);
}
int isSFR(int address)
{
- if( (address > pic->max_address) || !finalMapping[address].isSFR)
+ if( (address > pic->maxRAMaddress) || !finalMapping[address].isSFR)
return 0;
return 1;
{
int i;
- if(address > pic->max_address)
+ if(address > pic->maxRAMaddress)
return 0;
for (i=0; i<reg_size; i++)
int i;
int alias;
-
+ if(!reg || !reg->size) {
+ fprintf(stderr,"WARNING: %s:%s:%d Bad register\n",__FILE__,__FUNCTION__,__LINE__);
+ return;
+ }
for(i=0; i<reg->size; i++) {
do {
- //fprintf(stdout,"mapping %s to address 0x%02x\n",reg->name, (reg->address+alias+i));
+ // fprintf(stdout,"mapping %s to address 0x%02x, reg size = %d\n",reg->name, (reg->address+alias+i),reg->size);
finalMapping[reg->address + alias + i].reg = reg;
finalMapping[reg->address + alias + i].instance = i;
} while (alias>=0);
}
+ // fprintf(stderr,"%s - %s addr = 0x%03x, size %d\n",__FUNCTION__,reg->name, reg->address,reg->size);
+
reg->isMapped = 1;
}
{
int i;
+ //fprintf(stderr,"%s - %s start_address = 0x%03x\n",__FUNCTION__,reg->name, start_address);
if(reg->isFixed) {
if (validAddress(reg->address,reg->size)) {
* so we'll search through all availble ram address and
* assign the first one */
- for (i=start_address; i<=pic->max_address; i++) {
+ for (i=start_address; i<=pic->maxRAMaddress; i++) {
if (validAddress(i,reg->size)) {
reg->address = i;
for (reg = setFirstItem(regset) ; reg ;
reg = setNextItem(regset)) {
- //fprintf(stdout,"assigning %s\n",reg->name);
+ // fprintf(stdout,"assigning %s\n",reg->name);
if((!reg->isFixed) && ( (used==0) || reg->wasUsed))
address = assignRegister(reg,address);
memRange *ram; /* RAM memory map */
memRange *sfr; /* SFR memory map */
- int max_address; /* maximum value for a data address */
+ int maxRAMaddress; /* maximum value for a data address */
// int hasAliasedRAM:1; /* True if there are bank independent registers */
} PIC_device;
#include "gen.h"
+extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
+extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
+void genMult8X8_8 (operand *, operand *,operand *);
+
static int labelOffset=0;
static int debug_verbose=1;
static int optimized_for_speed = 0;
static int max_key=0;
static int GpsuedoStkPtr=0;
+pCodeOp *popGetImmd(char *name, unsigned int offset);
unsigned int pic14aopLiteral (value *val, int offset);
const char *AopType(short type);
static iCode *ifxForOp ( operand *op, iCode *ic );
}
+void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
+{
+
+ DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
+ line_no,
+ ((result) ? AopType(AOP_TYPE(result)) : "-"),
+ ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
+ ((left) ? AopType(AOP_TYPE(left)) : "-"),
+ ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
+ ((right) ? AopType(AOP_TYPE(right)) : "-"),
+ ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
+
+}
+
void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
{
va_list ap;
}
-static void emitpLabel(int key)
+void emitpLabel(int key)
{
addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
}
static asmop *aopForRemat (symbol *sym)
{
iCode *ic = sym->rematiCode;
- asmop *aop = newAsmop(AOP_IMMD);
+ //X asmop *aop = newAsmop(AOP_IMMD);
+ asmop *aop = newAsmop(AOP_PCODE);
int val = 0;
+ int offset = 0;
+
DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
+
for (;;) {
- if (ic->op == '+')
- val += (int) operandLitValue(IC_RIGHT(ic));
- else if (ic->op == '-')
- val -= (int) operandLitValue(IC_RIGHT(ic));
- else
+ if (ic->op == '+') {
+ val += (int) operandLitValue(IC_RIGHT(ic));
+ } else if (ic->op == '-') {
+ val -= (int) operandLitValue(IC_RIGHT(ic));
+ } else
break;
ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
}
-
- if (val)
+/* X
+ if (val) {
sprintf(buffer,"(%s %c 0x%04x)",
OP_SYMBOL(IC_LEFT(ic))->rname,
val >= 0 ? '+' : '-',
abs(val) & 0xffff);
- else
- strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
+ fprintf(stderr,"hmmm %s\n",buffer);
+ } else
+ strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
+*/
+ //ic = sym->rematiCode;
+ offset = OP_SYMBOL(IC_LEFT(ic))->offset;
+ aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,val);
+ DEBUGpic14_emitcode(";"," rname %s, val %d ",OP_SYMBOL(IC_LEFT(ic))->rname,val);
+ //X aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
+ //X strcpy(aop->aopu.aop_immd,buffer);
- //DEBUGpic14_emitcode(";","%s",buffer);
- aop->aopu.aop_immd = Safe_calloc(1,strlen(buffer)+1);
- strcpy(aop->aopu.aop_immd,buffer);
- //aop->aopu.aop_alloc_reg = allocDirReg (IC_LEFT(ic));
allocDirReg (IC_LEFT(ic));
+
return aop;
}
sym->aop = op->aop = aop =
aopForRemat (sym);
aop->size = getSize(sym->type);
+ //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
return;
}
/* force a new aop if sizes differ */
sym->usl.spillLoc->aop = NULL;
}
- DEBUGpic14_emitcode(";","%s %d %s",__FUNCTION__,__LINE__,sym->usl.spillLoc->rname);
- sym->aop = op->aop = aop =
- aopForSym(ic,sym->usl.spillLoc,result);
+ DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
+ __FUNCTION__,__LINE__,
+ sym->usl.spillLoc->rname,
+ sym->rname, sym->usl.spillLoc->offset);
+ // X sym->aop = op->aop = aop = aopForSym(ic,sym->usl.spillLoc,result);
+ sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+ aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,sym->usl.spillLoc->offset);
+ //allocDirReg (IC_LEFT(ic));
aop->size = getSize(sym->type);
+
return;
}
return rs;
case AOP_DIR:
- if (offset)
- sprintf(s,"(%s + %d)",
- aop->aopu.aop_dir,
- offset);
- else
+ if (offset) {
+ sprintf(s,"(%s + %d)",
+ aop->aopu.aop_dir,
+ offset);
+ DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
+ } else
sprintf(s,"%s",aop->aopu.aop_dir);
rs = Safe_calloc(1,strlen(s)+1);
strcpy(rs,s);
return aop->aopu.aop_str[offset];
+ case AOP_PCODE:
+ {
+ pCodeOp *pcop = aop->aopu.pcop;
+ DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE",__LINE__);
+ if(pcop->name) {
+ DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
+ //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
+ sprintf(s,"%s", pcop->name);
+ } else
+ sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
+
+ }
+ rs = Safe_calloc(1,strlen(s)+1);
+ strcpy(rs,s);
+ return rs;
+
}
werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
exit(0);
}
+
+/*-----------------------------------------------------------------*/
+/* popGetTempReg - create a new temporary pCodeOp */
+/*-----------------------------------------------------------------*/
+pCodeOp *popGetTempReg(void)
+{
+
+ pCodeOp *pcop;
+
+ pcop = newpCodeOp(NULL, PO_GPR_TEMP);
+ if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
+ PCOR(pcop)->r->wasUsed=1;
+ PCOR(pcop)->r->isFree=0;
+ }
+
+ return pcop;
+}
+
+/*-----------------------------------------------------------------*/
+/* popGetTempReg - create a new temporary pCodeOp */
+/*-----------------------------------------------------------------*/
+void popReleaseTempReg(pCodeOp *pcop)
+{
+
+ if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
+ PCOR(pcop)->r->isFree = 1;
+
+}
/*-----------------------------------------------------------------*/
/* popGetLabel - create a new pCodeOp of type PO_LABEL */
/*-----------------------------------------------------------------*/
pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
pcor->pcop.type = pc->pcop.type;
- if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
- fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
+ if(pc->pcop.name) {
+ if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
+ fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
+ } else
+ pcor->pcop.name = NULL;
+
pcor->r = pc->r;
pcor->rIdx = pc->rIdx;
pcor->r->wasUsed=1;
/*-----------------------------------------------------------------*/
pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
{
- char *s = buffer ;
+ //char *s = buffer ;
//char *rs;
pCodeOp *pcop;
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
pcop->type = PO_DIR;
+ /*
if (offset)
sprintf(s,"(%s + %d)",
aop->aopu.aop_dir,
sprintf(s,"%s",aop->aopu.aop_dir);
pcop->name = Safe_calloc(1,strlen(s)+1);
strcpy(pcop->name,s);
+ */
+ pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
+ strcpy(pcop->name,aop->aopu.aop_dir);
PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
- if(PCOR(pcop)->r == NULL)
- fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
- else
- PCOR(pcop)->instance = offset;
+ if(PCOR(pcop)->r == NULL) {
+ fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
+ PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
+ }
+
+ DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
+ PCOR(pcop)->instance = offset;
return pcop;
return pcop;
*/
+
+ case AOP_PCODE:
+ DEBUGpic14_emitcode(";","popGet AOP_PCODE%d",__LINE__);
+ return pCodeOpCopy(aop->aopu.pcop);
}
werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
/* depending on where it is ofcourse */
switch (aop->type) {
case AOP_DIR:
- if (offset)
- sprintf(d,"(%s + %d)",
- aop->aopu.aop_dir,offset);
- else
+ if (offset) {
+ sprintf(d,"(%s + %d)",
+ aop->aopu.aop_dir,offset);
+ fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
+
+ } else
sprintf(d,"%s",aop->aopu.aop_dir);
if (strcmp(d,s)) {
#define STRCASECMP strcasecmp
#endif
+#if 0
/*-----------------------------------------------------------------*/
/* inExcludeList - return 1 if the string is in exclude Reg list */
/*-----------------------------------------------------------------*/
static bool inExcludeList(char *s)
{
DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
-#if 0
int i =0;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
STRCASECMP(s,options.excludeRegs[i]) == 0)
return TRUE;
}
-#endif
return FALSE ;
}
+#endif
/*-----------------------------------------------------------------*/
/* genFunction - generated code for function entry */
operand *right,
operand *result)
{
- sym_link *opetype = operandType(result);
- char *l ;
- symbol *lbl ;
- int size,offset;
+ sym_link *opetype = operandType(result);
- DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
+ // symbol *lbl ;
+ int size,offset;
+
+ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
DEBUGpic14_AopType(__LINE__,left,right,result);
+ DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
+
+ /* (if two literals, the value is computed before) */
+ /* if one literal, literal on the right */
+ if (AOP_TYPE(left) == AOP_LIT){
+ operand *t = right;
+ right = left;
+ left = t;
+ }
+
+ size = AOP_SIZE(result);
+ if(size == 1) {
+
+ if (AOP_TYPE(right) == AOP_LIT){
+ pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
+ aopGet(AOP(right),0,FALSE,FALSE),
+ aopGet(AOP(left),0,FALSE,FALSE),
+ aopGet(AOP(result),0,FALSE,FALSE));
+ pic14_emitcode("call","genMultLit");
+ } else {
+ pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
+ aopGet(AOP(right),0,FALSE,FALSE),
+ aopGet(AOP(left),0,FALSE,FALSE),
+ aopGet(AOP(result),0,FALSE,FALSE));
+ pic14_emitcode("call","genMult8X8_8");
- /* (if two literals, the value is computed before) */
- /* if one literal, literal on the right */
- if (AOP_TYPE(left) == AOP_LIT){
- operand *t = right;
- right = left;
- left = t;
}
+ genMult8X8_8 (left, right,result);
+
- size = AOP_SIZE(result);
/* signed or unsigned */
- pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
- l = aopGet(AOP(left),0,FALSE,FALSE);
- MOVA(l);
- pic14_emitcode("mul","ab");
+ //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
+ //l = aopGet(AOP(left),0,FALSE,FALSE);
+ //MOVA(l);
+ //pic14_emitcode("mul","ab");
/* if result size = 1, mul signed = mul unsigned */
- aopPut(AOP(result),"a",0);
- if (size > 1){
- if (SPEC_USIGN(opetype)){
- aopPut(AOP(result),"b",1);
- if (size > 2)
- /* for filling the MSBs */
- pic14_emitcode("clr","a");
- }
- else{
- pic14_emitcode("mov","a,b");
+ //aopPut(AOP(result),"a",0);
- /* adjust the MSB if left or right neg */
+ } else { // (size > 1)
- /* if one literal */
- if (AOP_TYPE(right) == AOP_LIT){
- /* AND literal negative */
- if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
- /* adjust MSB (c==0 after mul) */
- pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
- }
- }
- else{
- lbl = newiTempLabel(NULL);
- pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
- pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
- pic14_emitcode("","%05d_DS_:",(lbl->key+100));
- pic14_emitcode("xch","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
- lbl = newiTempLabel(NULL);
- pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
- pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
- pic14_emitcode("","%05d_DS_:",(lbl->key+100));
- }
+ pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
+ aopGet(AOP(right),0,FALSE,FALSE),
+ aopGet(AOP(left),0,FALSE,FALSE),
+ aopGet(AOP(result),0,FALSE,FALSE));
- lbl = newiTempLabel(NULL);
- pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
- pic14_emitcode("cjne","a,#0x80,%05d_DS_", (lbl->key+100));
- pic14_emitcode("","%05d_DS_:",(lbl->key+100));
- pic14_emitcode("xch","a,%s",aopGet(AOP(left),0,FALSE,FALSE));
- lbl = newiTempLabel(NULL);
- pic14_emitcode("jc","%05d_DS_",(lbl->key+100));
- pic14_emitcode("subb","a,%s", aopGet(AOP(right),0,FALSE,FALSE));
- pic14_emitcode("","%05d_DS_:",(lbl->key+100));
+ if (SPEC_USIGN(opetype)){
+ pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
+ genUMult8X8_16 (left, right, result, NULL);
- aopPut(AOP(result),"a",1);
- if(size > 2){
- /* get the sign */
- pic14_emitcode("rlc","a");
- pic14_emitcode("subb","a,acc");
- }
- }
- size -= 2;
- offset = 2;
- if (size > 0)
- while (size--)
- aopPut(AOP(result),"a",offset++);
+ if (size > 2) {
+ /* for filling the MSBs */
+ emitpcode(POC_CLRF, popGet(AOP(result),2));
+ emitpcode(POC_CLRF, popGet(AOP(result),3));
+ }
+ }
+ else{
+ pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
+
+ pic14_emitcode("mov","a,b");
+
+ /* adjust the MSB if left or right neg */
+
+ /* if one literal */
+ if (AOP_TYPE(right) == AOP_LIT){
+ pic14_emitcode("multiply ","right is a lit");
+ /* AND literal negative */
+ if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
+ /* adjust MSB (c==0 after mul) */
+ pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
+ }
+ }
+ else{
+ genSMult8X8_16 (left, right, result, NULL);
+ }
+
+ if(size > 2){
+ pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
+ /* get the sign */
+ pic14_emitcode("rlc","a");
+ pic14_emitcode("subb","a,acc");
+ }
}
+
+ size -= 2;
+ offset = 2;
+ if (size > 0)
+ while (size--)
+ pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
+ //aopPut(AOP(result),"a",offset++);
+ }
}
/*-----------------------------------------------------------------*/
goto release ;
}
- /* should have been converted to function call */
- assert(0) ;
+ pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
+
+ /* should have been converted to function call */
+ //assert(0) ;
release :
freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
aopOp(result,ic,TRUE);
+ DEBUGpic14_AopType(__LINE__,left,NULL,result);
+
emitpcode(POC_MOVFW, popGet(AOP(left),0));
size = AOP_SIZE(result);
result is not bit variable type and
the left is pointer to data space i.e
lower 128 bytes of space */
- if (AOP_TYPE(left) == AOP_IMMD &&
+ if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
!IS_BITVAR(retype) &&
DCL_TYPE(ltype) == POINTER) {
- genDataPointerGet (left,result,ic);
+ //genDataPointerGet (left,result,ic);
return ;
}
static void genConstPointerGet (operand *left,
operand *result, iCode *ic)
{
- sym_link *retype = getSpec(operandType(result));
+ //sym_link *retype = getSpec(operandType(result));
symbol *albl = newiTempLabel(NULL);
symbol *blbl = newiTempLabel(NULL);
PIC_OPCODE poc;
l = aopGet(AOP(result),0,FALSE,TRUE);
size = AOP_SIZE(right);
+ if ( AOP_TYPE(result) == AOP_PCODE) {
+ fprintf(stderr,"genDataPointerSet %s, %d\n",
+ AOP(result)->aopu.pcop->name,
+ PCOI(AOP(result)->aopu.pcop)->offset);
+ }
+
// tsd, was l+1 - the underline `_' prefix was being stripped
while (size--) {
- if (offset)
- sprintf(buffer,"(%s + %d)",l,offset);
- else
- sprintf(buffer,"%s",l);
+ if (offset) {
+ sprintf(buffer,"(%s + %d)",l,offset);
+ fprintf(stderr,"oops %s\n",buffer);
+ } else
+ sprintf(buffer,"%s",l);
if (AOP_TYPE(right) == AOP_LIT) {
unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
pic14_emitcode("movwf","%s",buffer);
emitpcode(POC_MOVLW, popGetLit(lit&0xff));
- emitpcode(POC_MOVWF, popRegFromString(buffer));
+ //emitpcode(POC_MOVWF, popRegFromString(buffer));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
} else {
pic14_emitcode("clrf","%s",buffer);
//emitpcode(POC_CLRF, popRegFromString(buffer));
- emitpcode(POC_CLRF, popGet(AOP(result),offset));
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
}
}else {
pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
pic14_emitcode("movwf","%s",buffer);
emitpcode(POC_MOVFW, popGet(AOP(right),offset));
- emitpcode(POC_MOVWF, popRegFromString(buffer));
+ //emitpcode(POC_MOVWF, popRegFromString(buffer));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
}
/* if the result is rematerializable &
in data space & not a bit variable */
- if (AOP_TYPE(result) == AOP_IMMD &&
- DCL_TYPE(ptype) == POINTER &&
+ //if (AOP_TYPE(result) == AOP_IMMD &&
+ if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
+ DCL_TYPE(ptype) == POINTER &&
!IS_BITVAR(retype)) {
genDataPointerSet (right,result,ic);
return;
_G.debugLine = 0;
}
pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
+ pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
+ printCLine(ic->filename, ic->lineno));
+
cln = ic->lineno ;
}
/* if the result is marked as
#ifndef SDCCGENPIC14_H
#define SDCCGENPIC14_H
+struct pCodeOp;
+
enum
{
AOP_LIT = 1,
AOP_REG, AOP_DIR,
AOP_DPTR, AOP_DPTR2, AOP_R0, AOP_R1,
AOP_STK, AOP_IMMD, AOP_STR,
- AOP_CRY, AOP_ACC
+ AOP_CRY, AOP_ACC,
+ AOP_PCODE
+
};
/* type asmop : a homogenised type for
int aop_stk; /* stack offset when AOP_STK */
char *aop_str[4]; /* just a string array containing the location */
/* regs *aop_alloc_reg; * points to a dynamically allocated register */
+ pCodeOp *pcop;
}
aopu;
}
int pic14_getDataSize(operand *op);
void emitpcode(PIC_OPCODE poc, pCodeOp *pcop);
+void emitpLabel(int key);
void pic14_emitcode (char *inst,char *fmt, ...);
void DEBUGpic14_emitcode (char *inst,char *fmt, ...);
asmop *newAsmop (short type);
pCodeOp *popGetWithString(char *str);
pCodeOp *popRegFromString(char *str);
pCodeOp *popGet (asmop *aop, int offset);//, bool bit16, bool dname);
+pCodeOp *popGetTempReg(void);
+void popReleaseTempReg(pCodeOp *pcop);
void aopPut (asmop *aop, char *s, int offset);
case AOP_ACC:
return "AOP_ACC";
break;
+ case AOP_PCODE:
+ return "AOP_PCODE";
+ break;
}
return "BAD TYPE";
freeAsmop(IC_RIGHT(ic),NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
}
+/*-----------------------------------------------------------------*
+ * genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
+ *
+ *
+ *-----------------------------------------------------------------*/
+void genUMult8XLit_16 (operand *left,
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
+
+{
+
+ unsigned int lit;
+ unsigned int i,have_first_bit;
+
+ if (AOP_TYPE(right) != AOP_LIT){
+ fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+ exit(1);
+ }
+
+
+ if(!result_hi) {
+ result_hi = PCOR(popGet(AOP(result),1));
+ }
+
+ lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit &= 0xff;
+ pic14_emitcode(";","Unrolled 8 X 8 multiplication");
+
+
+ if(!lit) {
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ return;
+ }
+
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+
+ have_first_bit = 0;
+ for(i=0; i<8; i++) {
+
+ if(lit & 1) {
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+ have_first_bit = 1;
+ }
+
+ if(have_first_bit) {
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+ }
+
+ lit >>= 1;
+ }
+
+}
+
+/*-----------------------------------------------------------------*
+ * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
+ *
+ *
+ *-----------------------------------------------------------------*/
+void genUMult8X8_16 (operand *left,
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
+
+{
+
+ int i;
+ int looped = 1;
+
+ if(!result_hi) {
+ result_hi = PCOR(popGet(AOP(result),1));
+ }
+
+ if(!looped) {
+ pic14_emitcode(";","Unrolled 8 X 8 multiplication");
+
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitCLRC;
+
+ for(i=0; i<8; i++) {
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),i,0));
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+ }
+
+
+ /*
+ Here's another version that does the same thing and takes the
+ same number of instructions. The one above is slightly better
+ because the entry instructions have a higher probability of
+ being optimized out.
+ */
+ /*
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitpcode(POC_RRFW, popGet(AOP(left),0));
+ emitpcode(POC_MOVWF, popGet(AOP(result),0));
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+
+ for(i=0; i<8; i++) {
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+ }
+ */
+
+ } else {
+ symbol *tlbl = newiTempLabel(NULL);
+ pCodeOp *temp = popGetTempReg();
+
+
+ pic14_emitcode(";","Looped 8 X 8 multiplication");
+
+ emitpcode(POC_CLRF, popGet(AOP(result),0));
+ emitpcode(POC_CLRF, popCopyReg(result_hi));
+ emitpcode(POC_BSF, newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),7,0));
+
+ emitpcode(POC_MOVFW, popGet(AOP(right),0));
+ emitpcode(POC_MOVWF, popCopyReg(PCOR(temp)));
+
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpLabel(tlbl->key);
+ emitpcode(POC_RRF, popCopyReg(PCOR(temp)));
+ emitSKPNC;
+ emitpcode(POC_ADDWF, popCopyReg(result_hi));
+
+ emitpcode(POC_RRF, popCopyReg(result_hi));
+ emitpcode(POC_RRF, popGet(AOP(result),0));
+
+ emitSKPC;
+ emitpcode(POC_GOTO, popGetLabel(tlbl->key));
+
+ popReleaseTempReg(temp);
+
+ }
+}
+
+/*-----------------------------------------------------------------*
+ * genSMult8X8_16 - signed multiplication of two 8-bit numbers
+ *
+ * this routine will call the unsigned multiply routine and then
+ * post-fix the sign bit.
+ *-----------------------------------------------------------------*/
+void genSMult8X8_16 (operand *left,
+ operand *right,
+ operand *result,
+ pCodeOpReg *result_hi)
+{
+
+ if(!result_hi) {
+ result_hi = PCOR(popGet(AOP(result),1));
+ }
+
+ genUMult8X8_16(left,right,result,result_hi);
+
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),7,0));
+ emitpcode(POC_SUBWF, popCopyReg(result_hi));
+ emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),7,0));
+ emitpcode(POC_SUBWF, popGet(AOP(result),1));
+
+}
+
+/*-----------------------------------------------------------------*
+ * genMult8X8_8 - multiplication of two 8-bit numbers
+ *
+ * this routine will call the unsigned multiply 8X8=>16 routine and
+ * then throw away the high byte of the result.
+ *
+ *-----------------------------------------------------------------*/
+void genMult8X8_8 (operand *left,
+ operand *right,
+ operand *result)
+{
+ pCodeOp *result_hi = popGetTempReg();
+
+ if (AOP_TYPE(right) == AOP_LIT)
+ genUMult8XLit_16(left,right,result,PCOR(result_hi));
+ else
+ genUMult8X8_16(left,right,result,PCOR(result_hi));
+
+ popReleaseTempReg(result_hi);
+}
+#if 0
+/*-----------------------------------------------------------------*/
+/* constMult - generates code for multiplication by a constant */
+/*-----------------------------------------------------------------*/
+void genMultConst(unsigned C)
+{
+
+ unsigned lit;
+ unsigned sr3; // Shift right 3
+ unsigned mask;
+
+ int size = 1;
+
+ /*
+ Convert a string of 3 binary 1's in the lit into
+ 0111 = 1000 - 1;
+ */
+
+ mask = 7 << ( (size*8) - 3);
+ lit = C;
+ sr3 = 0;
+
+ while(mask < (1<<size*8)) {
+
+ if( (mask & lit) == lit) {
+ unsigned lsb;
+
+ /* We found 3 (or more) consecutive 1's */
+
+ lsb = mask & ~(mask & (mask-1)); // lsb of mask.
+
+ consecutive_bits = ((lit + lsb) & lit) ^ lit;
+
+ lit ^= consecutive_bits;
+
+ mask <<= 3;
+
+ sr3 |= (consecutive + lsb);
+
+ }
+
+ mask >>= 1;
+
+ }
+
+}
+
+#endif
return TRUE;
}
+static bool
+_hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
+{
+ sym_link *test = NULL;
+ value *val;
+
+ fprintf(stderr,"checking for native mult\n");
+
+ if ( ic->op != '*')
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+/*
+ if ( IS_LITERAL (left))
+ {
+ fprintf(stderr,"left is lit\n");
+ test = left;
+ val = OP_VALUE (IC_LEFT (ic));
+ }
+ else if ( IS_LITERAL (right))
+ {
+ fprintf(stderr,"right is lit\n");
+ test = left;
+ val = OP_VALUE (IC_RIGHT (ic));
+ }
+ else
+ {
+ fprintf(stderr,"oops, neither is lit so no\n");
+ return FALSE;
+ }
+
+ if ( getSize (test) <= 2)
+ {
+ fprintf(stderr,"yep\n");
+ return TRUE;
+ }
+ fprintf(stderr,"nope\n");
+
+ return FALSE;
+*/
+}
+
/** $1 is always the basename.
$2 is always the output file.
$3 varies
TARGET_ID_PIC,
"pic14",
"MCU pic", /* Target name */
- NULL, /* Processor */
+ "p16f877", /* Processor */
{
TRUE, /* Emit glue around main */
MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24,
NULL, // xinit
NULL,
NULL,
- 1
+ 1 // code is read only
},
{
+1, 1, 4, 1, 1, 0
_pic14_regparm,
NULL,
NULL,
- NULL,
+ _hasNativeMulFor,
FALSE,
0, /* leave lt */
0, /* leave gt */
#define STRCASECMP strcasecmp
#endif
+/****************************************************************/
+/****************************************************************/
+
+peepCommand peepCommands[] = {
+
+ {NOTBITSKIP, "_NOTBITSKIP_"},
+ {BITSKIP, "_BITSKIP_"},
+ {INVERTBITSKIP, "_INVERTBITSKIP_"},
+
+ {-1, NULL}
+};
+
+
// Eventually this will go into device dependent files:
pCodeOpReg pc_status = {{PO_STATUS, "STATUS"}, -1, NULL,0,NULL};
static hTab *pic14MnemonicsHash = NULL;
+static hTab *pic14pCodePeepCommandsHash = NULL;
static pFile *the_pFile = NULL;
-static int peepOptimizing = 1;
+static int peepOptimizing = 0;
static int GpCodeSequenceNumber = 1;
static int GpcFlowSeq = 1;
#define isPCI(x) ((PCODE(x)->type == PC_OPCODE))
#define isPCI_BRANCH(x) ((PCODE(x)->type == PC_OPCODE) && PCI(x)->isBranch)
#define isPCI_SKIP(x) ((PCODE(x)->type == PC_OPCODE) && PCI(x)->isSkip)
+#define isPCI_BITSKIP(x)((PCODE(x)->type == PC_OPCODE) && PCI(x)->isSkip && PCI(x)->isBitInst)
#define isPCFL(x) ((PCODE(x)->type == PC_FLOW))
#define isPCF(x) ((PCODE(x)->type == PC_FUNCTION))
#define isCALL(x) ((isPCI(x)) && (PCI(x)->op == POC_CALL))
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z) // outCond
};
// genericAnalyze,
genericDestruct,
genericPrint},
- POC_ADDWF,
+ POC_ADDFW,
"ADDWF",
NULL, // from branch
NULL, // to branch
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z) // outCond
};
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_W, // inCond
(PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
};
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_W, // inCond
(PCC_W | PCC_Z) // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z) // outCond
};
// genericAnalyze,
genericDestruct,
genericPrint},
- POC_ANDWF,
+ POC_ANDFW,
"ANDWF",
NULL, // from branch
NULL, // to branch
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z) // outCond
};
2, // num ops
1,1, // dest, bit instruction
0,0, // branch, skip
+ POC_BSF,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
};
2, // num ops
1,1, // dest, bit instruction
0,0, // branch, skip
+ POC_BCF,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
};
2, // num ops
0,1, // dest, bit instruction
1,1, // branch, skip
+ POC_BTFSS,
PCC_REGISTER, // inCond
PCC_NONE // outCond
};
2, // num ops
0,1, // dest, bit instruction
1,1, // branch, skip
+ POC_BTFSC,
PCC_REGISTER, // inCond
PCC_NONE // outCond
};
1, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
+ POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
};
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
};
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
};
0, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_W, // inCond
PCC_W // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
};
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
};
2, // num ops
1,0, // dest, bit instruction
1,1, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
};
2, // num ops
0,0, // dest, bit instruction
1,1, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
};
1, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
+ POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
};
-
pCodeInstruction pciINCF = {
{PC_OPCODE, NULL, NULL, 0, NULL,
// genericAnalyze,
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
};
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
};
2, // num ops
1,0, // dest, bit instruction
1,1, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_REGISTER // outCond
};
2, // num ops
0,0, // dest, bit instruction
1,1, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_W // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z) // outCond
};
// genericAnalyze,
genericDestruct,
genericPrint},
- POC_IORWF,
+ POC_IORFW,
"IORWF",
NULL, // from branch
NULL, // to branch
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z) // outCond
};
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_W, // inCond
(PCC_W | PCC_Z) // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
PCC_Z // outCond
};
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_REGISTER, // inCond
(PCC_W | PCC_Z) // outCond
};
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_W, // inCond
PCC_REGISTER // outCond
};
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_NONE, // inCond
PCC_W // outCond
};
0, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
};
0, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
+ POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond (not true... affects the GIE bit too)
};
1, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
+ POC_NOP,
PCC_NONE, // inCond
PCC_W // outCond
};
0, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
+ POC_NOP,
PCC_NONE, // inCond
PCC_NONE // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
};
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
(PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
};
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_C | PCC_REGISTER), // inCond
(PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z) // outCond
};
// genericAnalyze,
genericDestruct,
genericPrint},
- POC_SUBWF,
+ POC_SUBFW,
"SUBWF",
NULL, // from branch
NULL, // to branch
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z) // outCond
};
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_W, // inCond
(PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_REGISTER), // inCond
(PCC_REGISTER) // outCond
};
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_REGISTER), // inCond
(PCC_W) // outCond
};
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_NONE, // inCond
PCC_REGISTER // outCond
};
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_REGISTER | PCC_Z) // outCond
};
// genericAnalyze,
genericDestruct,
genericPrint},
- POC_XORWF,
+ POC_XORFW,
"XORWF",
NULL, // from branch
NULL, // to branch
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
(PCC_W | PCC_REGISTER), // inCond
(PCC_W | PCC_Z) // outCond
};
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
+ POC_NOP,
PCC_W, // inCond
(PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
};
extern void initStack(int base_address, int size);
extern regs *allocProcessorRegister(int rIdx, char * name, short po_type, int alias);
extern regs *allocInternalRegister(int rIdx, char * name, short po_type, int alias);
-extern void init_pic(void);
+extern void init_pic(char *);
void pCodeInitRegisters(void)
{
initStack(0x38, 8);
- init_pic();
+ init_pic(port->processor);
pc_status.r = allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80);
pc_pcl.r = allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
if(mnemonics_initialized)
return;
+//FIXME - probably should NULL out the array before making the assignments
+//since we check the array contents below this initialization.
+
pic14Mnemonics[POC_ADDLW] = &pciADDLW;
pic14Mnemonics[POC_ADDWF] = &pciADDWF;
pic14Mnemonics[POC_ADDFW] = &pciADDFW;
mnemonics_initialized = 1;
}
+int getpCodePeepCommand(char *cmd);
+
int getpCode(char *mnem,unsigned dest)
{
return -1;
}
+/*-----------------------------------------------------------------*
+ * pic14initpCodePeepCommands
+ *
+ *-----------------------------------------------------------------*/
+void pic14initpCodePeepCommands(void)
+{
+
+ int key, i;
+ peepCommand *pcmd;
+
+ i = 0;
+ do {
+ hTabAddItem(&pic14pCodePeepCommandsHash,
+ mnem2key(peepCommands[i].cmd), &peepCommands[i]);
+ i++;
+ } while (peepCommands[i].cmd);
+
+ pcmd = hTabFirstItem(pic14pCodePeepCommandsHash, &key);
+
+ while(pcmd) {
+ //fprintf(stderr, "peep command %s key %d\n",pcmd->cmd,pcmd->id);
+ pcmd = hTabNextItem(pic14pCodePeepCommandsHash, &key);
+ }
+
+}
+
+/*-----------------------------------------------------------------
+ *
+ *
+ *-----------------------------------------------------------------*/
+
+int getpCodePeepCommand(char *cmd)
+{
+
+ peepCommand *pcmd;
+ int key = mnem2key(cmd);
+
+
+ pcmd = hTabFirstItemWK(pic14pCodePeepCommandsHash, key);
+
+ while(pcmd) {
+ // fprintf(stderr," comparing %s to %s\n",pcmd->cmd,cmd);
+ if(STRCASECMP(pcmd->cmd, cmd) == 0) {
+ return pcmd->id;
+ }
+
+ pcmd = hTabNextItemWK (pic14pCodePeepCommandsHash);
+
+ }
+
+ return -1;
+}
+
char getpBlock_dbName(pBlock *pb)
{
if(!pb)
pcw->operand = optional_operand;
pcw->label = optional_label;
+ pcw->mustBeBitSkipInst = 0;
+ pcw->mustNotBeBitSkipInst = 0;
+ pcw->invertBitSkipInst = 0;
+
return ( (pCode *)pcw);
}
{
pCodeOp *pcop;
-
pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
pcop->type = PO_IMMEDIATE;
if(name) {
pcop->name = Safe_strdup(name);
+ fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
} else {
pcop->name = NULL;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
-pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
+pCodeOp *newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype)
{
char *s = buffer;
pCodeOp *pcop;
- if(!pcp || !subtype) {
+ if(!pcwb || !subtype) {
fprintf(stderr, "Wild opcode declaration error: %s-%d\n",__FILE__,__LINE__);
exit(1);
}
pcop->name = Safe_strdup(s);
PCOW(pcop)->id = id;
- PCOW(pcop)->pcp = pcp;
+ PCOW(pcop)->pcwb = pcwb;
PCOW(pcop)->subtype = subtype;
PCOW(pcop)->matched = NULL;
return pcop;
}
+/*-----------------------------------------------------------------*
+ * pCodeOp *newpCodeOpReg(int rIdx) - allocate a new register
+ *
+ * If rIdx >=0 then a specific register from the set of registers
+ * will be selected. If rIdx <0, then a new register will be searched
+ * for.
+ *-----------------------------------------------------------------*/
+
pCodeOp *newpCodeOpReg(int rIdx)
{
pCodeOp *pcop;
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
pcop->name = NULL;
- PCOR(pcop)->rIdx = rIdx;
- PCOR(pcop)->r = pic14_regWithIdx(rIdx);
+
+ if(rIdx >= 0) {
+ PCOR(pcop)->rIdx = rIdx;
+ PCOR(pcop)->r = pic14_regWithIdx(rIdx);
+ } else {
+ PCOR(pcop)->r = pic14_findFreeReg(REG_GPR);
+
+ if(PCOR(pcop)->r)
+ PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
+ //fprintf(stderr, "newpcodeOpReg - rIdx = %d\n", PCOR(pcop)->r->rIdx);
+ }
+
pcop->type = PCOR(pcop)->r->pc_type;
return pcop;
}
+
pCodeOp *newpCodeOpRegFromStr(char *name)
{
pCodeOp *pcop;
pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
- PCOR(pcop)->r = allocRegByName(name);
+ PCOR(pcop)->r = allocRegByName(name, 1);
PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
pcop->type = PCOR(pcop)->r->pc_type;
pcop->name = PCOR(pcop)->r->name;
case PO_LABEL:
pcop = newpCodeOpLabel(NULL,-1);
break;
+ case PO_GPR_TEMP:
+ pcop = newpCodeOpReg(-1);
+ break;
default:
pcop = Safe_calloc(1,sizeof(pCodeOp) );
case PO_IMMEDIATE:
s = buffer;
size = sizeof(buffer);
+
+
+/*
if( PCOI(pcc->pcop)->offset && PCOI(pcc->pcop)->offset<4) {
SAFE_snprintf(&s,&size,"((%s >> %d)&0xff)",
pcc->pcop->name,
8 * PCOI(pcc->pcop)->offset );
} else
SAFE_snprintf(&s,&size,"LOW(%s)",pcc->pcop->name);
+*/
-
+ if( PCOI(pcc->pcop)->offset && PCOI(pcc->pcop)->offset<4) {
+ SAFE_snprintf(&s,&size,"(%s + %d)",
+ pcc->pcop->name,
+ PCOI(pcc->pcop)->offset );
+ } else
+ SAFE_snprintf(&s,&size,"%s",pcc->pcop->name);
+ return buffer;
+
+ case PO_DIR:
+ s = buffer;
+ size = sizeof(buffer);
+ if( PCOR(pcc->pcop)->instance) {
+ SAFE_snprintf(&s,&size,"(%s + %d)",
+ pcc->pcop->name,
+ PCOR(pcc->pcop)->instance );
+ fprintf(stderr,"PO_DIR %s\n",buffer);
+ } else
+ SAFE_snprintf(&s,&size,"%s",pcc->pcop->name);
return buffer;
default:
}
/*-----------------------------------------------------------------*/
-/* popCopy - copy a pcode operator */
+/* popCopyGPR2Bit - copy a pcode operator */
/*-----------------------------------------------------------------*/
+
pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
{
pCodeOp *pcop;
if (PCF(pc)->fname) {
if(STRCASECMP(PCF(pc)->fname, "_main") == 0) {
- fprintf(stderr," found main \n");
+ //fprintf(stderr," found main \n");
pb->cmemmap = NULL; /* FIXME do we need to free ? */
pb->dbName = 'M';
}
* The double parenthesis (()) are necessary
*
***********************************************************************/
-#define PCODE_DEBUG
+//#define PCODE_DEBUG
#ifdef PCODE_DEBUG
#define DFPRINTF(args) (fprintf args)
/*************** Structures ********************/
/************************************************/
struct pCode;
+struct pCodeWildBlock;
/*************************************************
pBranch
} pCodeOpRegBit;
+typedef struct pCodeOpWild
+{
+ pCodeOp pcop;
+
+ struct pCodeWildBlock *pcwb;
+
+ int id; /* index into an array of char *'s that will match
+ * the wild card. The array is in *pcp. */
+ pCodeOp *subtype; /* Pointer to the Operand type into which this wild
+ * card will be expanded */
+ pCodeOp *matched; /* When a wild matches, we'll store a pointer to the
+ * opcode we matched */
+
+} pCodeOpWild;
+
+
/*************************************************
pCode
unsigned int isBranch: 1; /* True if this is a branching instruction */
unsigned int isSkip: 1; /* True if this is a skip instruction */
+ PIC_OPCODE inverted_op; /* Opcode of instruction that's the opposite of this one */
unsigned int inCond; // Input conditions for this instruction
unsigned int outCond; // Output conditions for this instruction
* - this wild card will get expanded into that pCode
* that is stored at this index */
+ /* Conditions on wild pcode instruction */
+ int mustBeBitSkipInst:1;
+ int mustNotBeBitSkipInst:1;
+ int invertBitSkipInst:1;
pCodeOp *operand; // Optional operand
pCodeOp *label; // Optional label
+/*************************************************
+ pCodeWildBlock
+
+ The pCodeWildBlock object keeps track of the wild
+ variables, operands, and opcodes that exist in
+ a pBlock.
+**************************************************/
+typedef struct pCodeWildBlock {
+ pBlock *pb;
+ struct pCodePeep *pcp; // pointer back to ... I don't like this...
+
+ int nvars; // Number of wildcard registers in target.
+ char **vars; // array of pointers to them
+
+ int nops; // Number of wildcard operands in target.
+ pCodeOp **wildpCodeOps; // array of pointers to the pCodeOp's.
+
+ int nwildpCodes; // Number of wildcard pCodes in target/replace
+ pCode **wildpCodes; // array of pointers to the pCode's.
+
+} pCodeWildBlock;
+
/*************************************************
pCodePeep
pCode chain.
**************************************************/
typedef struct pCodePeep {
+ pCodeWildBlock target; // code we'd like to optimize
+ pCodeWildBlock replace; // and this is what we'll optimize it with.
- pBlock *target; // code we'd like to optimize
- pBlock *replace; // and this is what we'll optimize it with.
+ //pBlock *target;
+ //pBlock replace; // and this is what we'll optimize it with.
- int nvars; // Number of wildcard registers in target.
- char **vars; // array of pointers to them
- int nops; // Number of wildcard operands in target.
- pCodeOp **wildpCodeOps; // array of pointers to the pCodeOp's.
-
- int nwildpCodes; // Number of wildcard pCodes in target/replace
- pCode **wildpCodes; // array of pointers to the pCode's.
/* (Note: a wildcard register is a place holder. Any register
} pCodePeep;
-typedef struct pCodeOpWild
-{
- pCodeOp pcop;
- //PIC_OPTYPE subtype; Wild get's expanded to this by the optimizer
- pCodePeep *pcp; // pointer to the parent peep block
- int id; /* index into an array of char *'s that will match
- * the wild card. The array is in *pcp. */
- pCodeOp *subtype; /* Pointer to the Operand type into which this wild
- * card will be expanded */
- pCodeOp *matched; /* When a wild matches, we'll store a pointer to the
- * opcode we matched */
+/*************************************************
+
+ pCode peep command definitions
+
+ Here are some special commands that control the
+way the peep hole optimizer behaves
+
+**************************************************/
+
+enum peepCommandTypes{
+ NOTBITSKIP = 0,
+ BITSKIP,
+ INVERTBITSKIP,
+ _LAST_PEEP_COMMAND_
+};
+
+/*************************************************
+ peepCommand structure stores the peep commands.
+
+**************************************************/
+
+typedef struct peepCommand {
+ int id;
+ char *cmd;
+} peepCommand;
-} pCodeOpWild;
/*************************************************
pCode Macros
#define PBR(x) ((pBranch *)(x))
+#define PCWB(x) ((pCodeWildBlock *)(x))
+
/*-----------------------------------------------------------------*
* pCode functions.
*-----------------------------------------------------------------*/
pCodeOp *newpCodeOpBit(char *name, int bit,int inBitSpace);
pCodeOp *newpCodeOpRegFromStr(char *name);
pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p);
+pCodeOp *pCodeOpCopy(pCodeOp *pcop);
+
extern void pcode_test(void);
/*-----------------------------------------------------------------*
pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval);
-pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype);
+pCodeOp *newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype);
pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label);
pCode * findNextInstruction(pCode *pc);
int getpCode(char *mnem,int dest);
+int getpCodePeepCommand(char *cmd);
void pBlockMergeLabels(pBlock *pb);
char *pCode2str(char *str, int size, pCode *pc);
extern pCodeInstruction *pic14Mnemonics[];
+#define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
+
/****************************************************************/
/*
* rootRules - defined in SDCCpeep.c
/* */
/****************************************************************/
-static pCodePeep *curPeep=NULL;
+//static pCodePeep *curPeep=NULL;
/****************************************************************/
/* */
/* */
/****************************************************************/
-static pBlock *curBlock=NULL;
+//static pBlock *curBlock=NULL;
/****************************************************************/
/* */
/****************************************************************/
-static int sMaxWildVar = 0;
-static int sMaxWildMnem = 0;
+//static int sMaxWildVar = 0;
+//static int sMaxWildMnem = 0;
typedef struct pCodeToken
PCT_NULL=0,
PCT_SPACE=1,
PCT_PERCENT,
+ PCT_LESSTHAN,
+ PCT_GREATERTHAN,
PCT_COLON,
PCT_COMMA,
PCT_COMMENT,
typedef struct pcPattern {
char pt; // Pattern type
char *tokens; // list of tokens that describe the pattern
- void * (*f) (void *);
+ void * (*f) (void *,pCodeWildBlock *);
} pcPattern;
pcPattern pcpArr[] = {
static char alt_mnem2[] = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
static char alt_mnem2a[] = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
-static void * cvt_altpat_label(void *pp);
-static void * cvt_altpat_comment(void *pp);
-static void * cvt_altpat_mnem0(void *pp);
-static void * cvt_altpat_mnem0a(void *pp);
-static void * cvt_altpat_mnem1(void *pp);
-static void * cvt_altpat_mnem1a(void *pp);
-static void * cvt_altpat_mnem1b(void *pp);
-static void * cvt_altpat_mnem2(void *pp);
-static void * cvt_altpat_mnem2a(void *pp);
+static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem0a(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb);
pcPattern altArr[] = {
{ALT_LABEL, alt_label, cvt_altpat_label},
/* at this point, we wish to extract only the 'number' */
/* */
/*-----------------------------------------------------------------*/
-static void * cvt_altpat_label(void *pp)
+static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb)
{
parsedPattern *p = pp;
/* */
/* */
/*-----------------------------------------------------------------*/
-static void * cvt_altpat_comment(void *pp)
+static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb)
{
parsedPattern *p = pp;
}
/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem0 - convert assembly line type to a wild pCode */
+/* instruction */
+/* */
+/* pp[0] - str */
+/* */
/*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem0(void *pp)
+static void * cvt_altpat_mnem0(void *pp,pCodeWildBlock *pcwb)
{
parsedPattern *p = pp;
int opcode;
DFPRINTF((stderr,"altpat_mnem0 %s\n", p->pct[0].tok.s));
opcode = getpCode(p->pct[0].tok.s,0);
+
if(opcode < 0) {
- fprintf(stderr, "Bad mnemonic\n");
+ /* look for special command strings like _NOTBITSKIP_ */
+
+ //fprintf(stderr, "Bad mnemonic\n");
+
+ opcode = getpCodePeepCommand(p->pct[0].tok.s);
+ //if(opcode > 0)
+ // fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
return NULL;
}
/* pp[0] - wild var */
/* */
/*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem0a(void *pp)
+static void * cvt_altpat_mnem0a(void *pp, pCodeWildBlock *pcwb)
{
parsedPattern *p = pp;
/* Save the index of the maximum wildcard mnemonic */
- if(p[0].pct[1].tok.n > sMaxWildVar)
- sMaxWildMnem = p[0].pct[1].tok.n;
+ //if(p[0].pct[1].tok.n > sMaxWildVar)
+ // sMaxWildMnem = p[0].pct[1].tok.n;
+
+ if(p[0].pct[1].tok.n > pcwb->nvars)
+ pcwb->nwildpCodes = p[0].pct[1].tok.n;
return newpCodeWild(p[0].pct[1].tok.n,NULL,NULL);
/* pp[1] - Operand */
/* */
/*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem1(void *pp)
+static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb)
{
parsedPattern *p = pp;
opcode = getpCode(p->pct[0].tok.s,0);
if(opcode < 0) {
- fprintf(stderr, "Bad mnemonic\n");
+ //fprintf(stderr, "Bad mnemonic\n");
+ opcode = getpCodePeepCommand(p->pct[0].tok.s);
+ //if(opcode > 0)
+ //fprintf(stderr," but valid peep command: %s, key = %d\n",p->pct[0].tok.s,opcode);
+
return NULL;
}
/* pp[1] - wild var */
/* */
/*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem1a(void *pp)
+static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb)
{
parsedPattern *p = pp;
int opcode;
opcode = getpCode(p->pct[0].tok.s,0);
if(opcode < 0) {
- fprintf(stderr, "Bad mnemonic\n");
- return NULL;
+ int cmd_id = getpCodePeepCommand(p->pct[0].tok.s);
+ pCode *pc=NULL;
+
+ if(cmd_id<0) {
+ fprintf(stderr, "Bad mnemonic\n");
+ return NULL;
+ }
+
+ if(p[0].pct[1].tok.n > pcwb->nvars)
+ pcwb->nwildpCodes = p[0].pct[1].tok.n;
+
+ pc = newpCodeWild(p[1].pct[1].tok.n,NULL,NULL);
+
+ switch(cmd_id) {
+ case NOTBITSKIP:
+ PCW(pc)->mustNotBeBitSkipInst = 1;
+ break;
+ case BITSKIP:
+ PCW(pc)->mustBeBitSkipInst = 1;
+ break;
+ case INVERTBITSKIP:
+ PCW(pc)->invertBitSkipInst = 1;
+ }
+ return pc;
}
if(pic14Mnemonics[opcode]->isBitInst)
pci = PCI(newpCode(opcode,
- newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype)));
+ newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
/* Save the index of the maximum wildcard variable */
- if(p[1].pct[1].tok.n > sMaxWildVar)
- sMaxWildVar = p[1].pct[1].tok.n;
+ //if(p[1].pct[1].tok.n > sMaxWildVar)
+ // sMaxWildVar = p[1].pct[1].tok.n;
+
+ if(p[1].pct[1].tok.n > pcwb->nvars)
+ pcwb->nvars = p[1].pct[1].tok.n;
if(!pci)
fprintf(stderr,"couldn't find mnemonic\n");
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem1b(void *pp)
+static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb)
{
parsedPattern *p = pp;
int opcode;
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem2(void *pp)
+static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
{
parsedPattern *p = pp;
int opcode;
/* pp[3] - destination */
/* */
/*-----------------------------------------------------------------*/
-static void * cvt_altpat_mnem2a(void *pp)
+static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
{
parsedPattern *p = pp;
int opcode;
pci = PCI(newpCode(opcode,
- newpCodeOpWild(p[1].pct[1].tok.n, curPeep, pcosubtype)));
+ newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
/* Save the index of the maximum wildcard variable */
- if(p[1].pct[1].tok.n > sMaxWildVar)
- sMaxWildVar = p[1].pct[1].tok.n;
+ //if(p[1].pct[1].tok.n > sMaxWildVar)
+ // sMaxWildVar = p[1].pct[1].tok.n;
+
+ if(p[1].pct[1].tok.n > pcwb->nvars)
+ pcwb->nvars = p[1].pct[1].tok.n;
if(!pci)
fprintf(stderr,"couldn't find mnemonic\n");
case '%':
tokArr[tokIdx++].tt = PCT_PERCENT;
break;
+ case '<':
+ tokArr[tokIdx++].tt = PCT_LESSTHAN;
+ break;
+ case '>':
+ tokArr[tokIdx++].tt = PCT_GREATERTHAN;
+ break;
case ':':
tokArr[tokIdx++].tt = PCT_COLON;
break;
default:
- if(isalpha(*ln)) {
+ if(isalpha(*ln) || (*ln == '_') ) {
char buffer[50];
int i=0;
- while( (isalpha(*ln) || isdigit(*ln)) && i<49)
+ while( (isalpha(*ln) || isdigit(*ln) || (*ln == '_')) && i<49)
buffer[i++] = *ln++;
ln--;
fprintf(stderr, " space ");
break;
case PCT_PERCENT:
- fprintf(stderr, " pct ");
- fputc('%', stderr);
+ fprintf(stderr, " pct %%");
+ break;
+ case PCT_LESSTHAN:
+ fprintf(stderr, " pct <");
+ break;
+ case PCT_GREATERTHAN:
+ fprintf(stderr, " pct >");
break;
case PCT_COLON:
- fprintf(stderr, " col ");
- fputc(':',stderr);
+ fprintf(stderr, " col :");
break;
case PCT_COMMA:
fprintf(stderr, " comma , ");
/* pcode. */
/*-----------------------------------------------------------------*/
-void parseTokens(void)
+void parseTokens(pCodeWildBlock *pcwb)
{
unsigned i;
pCode *pc;
if( (c=altComparePattern( altArr[k].tokens, &parsedPatArr[j],10) ) ) {
if( altArr[k].f) {
- pc = altArr[k].f(&parsedPatArr[j]);
+ pc = altArr[k].f(&parsedPatArr[j],pcwb);
//if(pc && pc->print)
// pc->print(stderr,pc);
//if(pc && pc->destruct) pc->destruct(pc); dumps core?
- if(curBlock && pc)
- addpCode2pBlock(curBlock, pc);
+
+ //if(curBlock && pc)
+ //addpCode2pBlock(curBlock, pc);
+ addpCode2pBlock(pcwb->pb, pc);
}
j += c;
}
/*-----------------------------------------------------------------*/
/* */
/*-----------------------------------------------------------------*/
-void peepRuleBlock2pCodeBlock( lineNode *ln)
+void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb)
{
if(!ln)
//DFPRINTF((stderr,"%s\n",ln->line));
tokenizeLineNode(ln->line);
- parseTokens();
+ parseTokens(pcwb);
}
}
/*-----------------------------------------------------------------*/
/* peepRuleCondition */
/*-----------------------------------------------------------------*/
-static void peepRuleCondition(char *cond)
+static void peepRuleCondition(char *cond, pCodePeep *pcp)
{
- if(!cond)
+ if(!cond || !pcp)
return;
//DFPRINTF((stderr,"\nCondition: %s\n",cond));
-
/* brute force compares for now */
if(STRCASECMP(cond, "NZ") == 0) {
//DFPRINTF((stderr,"found NZ\n"));
- curPeep->postFalseCond = PCC_Z;
+ pcp->postFalseCond = PCC_Z;
}
}
+
+
+void initpCodeWildBlock(pCodeWildBlock *pcwb)
+{
+
+ // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
+
+ if(!pcwb)
+ return;
+
+ pcwb->vars = NULL;
+ pcwb->wildpCodes = NULL;
+ pcwb->wildpCodeOps = NULL;
+
+ pcwb->nvars = 0;
+ pcwb->nwildpCodes = 0;
+ pcwb->nops = 0;
+
+}
+
+void postinit_pCodeWildBlock(pCodeWildBlock *pcwb)
+{
+
+ if(!pcwb)
+ return;
+
+ pcwb->nvars++;
+ pcwb->nops = pcwb->nvars;
+
+ pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *));
+ pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *));
+
+ pcwb->nwildpCodes++;
+ pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *));
+
+}
+
+void initpCodePeep(pCodePeep *pcp)
+{
+
+ // pcwb = Safe_calloc(1,sizeof(pCodeWildBlock));
+
+ if(!pcp)
+ return;
+
+ initpCodeWildBlock(&pcp->target);
+ pcp->target.pb = newpCodeChain(NULL, 'W', NULL);
+
+ initpCodeWildBlock(&pcp->replace);
+ pcp->replace.pb = newpCodeChain(NULL, 'W', NULL);
+
+}
+
/*-----------------------------------------------------------------*/
/* peepRules2pCode - parse the "parsed" peep hole rules to generate*/
/* pCode. */
/* taking raw text to produce machine code, it produces pCode. */
/* */
/*-----------------------------------------------------------------*/
+extern void pic14initpCodePeepCommands(void);
void peepRules2pCode(peepRule *rules)
{
peepRule *pr;
+ pCodePeep *currentRule;
pCodePeepSnippets *pcps;
+ pic14initpCodePeepCommands();
+
/* The rules are in a linked-list. Each rule has two portions */
/* There's the `target' and there's the `replace'. The target */
/* is compared against the SDCC generated code and if it */
//DFPRINTF((stderr,"\nRule:\n\n"));
pcps = Safe_calloc(1,sizeof(pCodePeepSnippets));
+ peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
+
+/*
curPeep = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
curPeep->vars = NULL;
curPeep->postFalseCond = PCC_NONE;
curPeep->postTrueCond = PCC_NONE;
- peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps);
curPeep->target = curBlock = newpCodeChain(NULL, 'W', NULL);
sMaxWildVar = 0;
sMaxWildMnem = 0;
+*/
+ currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep));
+ initpCodePeep(currentRule);
/* Convert the target block */
- peepRuleBlock2pCodeBlock(pr->match);
+ peepRuleBlock2pCodeBlock(pr->match, ¤tRule->target);
//DFPRINTF((stderr,"finished target, here it is in pcode form:\n"));
//printpBlock(stderr, curBlock);
//DFPRINTF((stderr,"target with labels merged:\n"));
- pBlockMergeLabels(curBlock);
-#ifdef PCODE_DEBUG
- printpBlock(stderr, curBlock);
-#endif
+ //pBlockMergeLabels(curBlock);
+ pBlockMergeLabels(currentRule->target.pb);
+ //printpBlock(stderr, currentRule->replace.pb);
+ //#ifdef PCODE_DEBUG
+ // printpBlock(stderr, curBlock);
+ //#endif
//DFPRINTF((stderr,"\nReplaced by:\n"));
- curPeep->replace = curBlock = newpCodeChain(NULL, 'W', NULL);
+ //curPeep->replace = curBlock = newpCodeChain(NULL, 'W', NULL);
/* Convert the replace block */
- peepRuleBlock2pCodeBlock(pr->replace);
+ peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace);
//DFPRINTF((stderr,"finished replace block, here it is in pcode form:\n"));
//printpBlock(stderr, curBlock);
//DFPRINTF((stderr,"replace with labels merged:\n"));
- pBlockMergeLabels(curBlock);
- //printpBlock(stderr, curBlock);
+ //pBlockMergeLabels(curBlock);
+ pBlockMergeLabels(currentRule->replace.pb);
+ //printpBlock(stderr, currentRule->replace.pb);
- peepRuleCondition(pr->cond);
+ peepRuleCondition(pr->cond,currentRule);
/* The rule has been converted to pCode. Now allocate
* space for the wildcards */
-
+
+/*
++sMaxWildVar;
curPeep->nvars = sMaxWildVar;
curPeep->vars = Safe_calloc(sMaxWildVar, sizeof(char *));
curPeep->nwildpCodes = ++sMaxWildMnem;
curPeep->wildpCodes = Safe_calloc(sMaxWildMnem, sizeof(char *));
-
+*/
+ postinit_pCodeWildBlock(¤tRule->target);
//return; // debug ... don't want to go through all the rules yet
}
+ {
+ pCodePeep *peepBlock;
+ _DLL *peeprules;
+
+ peeprules = (_DLL *)peepSnippets;
+ //fprintf(stderr,"target rules\n");
+ while(peeprules) {
+ //fprintf(stderr," rule:\n");
+ peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
+ //printpBlock(stderr, peepBlock->target.pb);
+ peeprules = peeprules->next;
+ }
+ //fprintf(stderr," ... done\n");
+ }
+
}
void printpCodeString(FILE *of, pCode *pc, int max)
labindex = -PCL(pcl)->key;
//DFPRINTF((stderr,"label id = %d (labindex = %d)\n",PCL(pcl)->key,labindex));
- if(peepBlock->vars[labindex] == NULL) {
+ if(peepBlock->target.vars[labindex] == NULL) {
// First time to encounter this label
- peepBlock->vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
+ peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label;
//DFPRINTF((stderr,"first time for a label: %d %s\n",labindex, peepBlock->vars[labindex]));
} else {
- if(strcmp(peepBlock->vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
+ if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) {
// DFPRINTF((stderr,"labels don't match\n"));
return 0;
}
{
int index; // index into wild card arrays
+ /* one-for-one match. Here the source and destination opcodes
+ * are not wild. However, there may be a label or a wild operand */
+
if(pcs->type == pcd->type) {
if(pcs->type == PC_OPCODE) {
}
#endif
PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
- if(!peepBlock->wildpCodeOps[index]) {
- peepBlock->wildpCodeOps[index] = PCI(pcs)->pcop;
+ if(!peepBlock->target.wildpCodeOps[index]) {
+ peepBlock->target.wildpCodeOps[index] = PCI(pcs)->pcop;
//if(PCI(pcs)->pcop->type == PO_GPR_TEMP)
n = PCI(pcs)->pcop->name;
}
- if(peepBlock->vars[index])
- return (strcmp(peepBlock->vars[index],n) == 0);
+ if(peepBlock->target.vars[index])
+ return (strcmp(peepBlock->target.vars[index],n) == 0);
else {
// DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
- peepBlock->vars[index] = n;
+ peepBlock->target.vars[index] = n;
return 1;
}
}
}
}
+ /* Compare a wild instruction to a regular one. */
if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) {
//pcs->print(stderr,pcs);
//pcd->print(stderr,pcd);
- peepBlock->wildpCodes[PCW(pcd)->id] = pcs;
+ peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs;
if(!pCodePeepMatchLabels(peepBlock, pcs, pcd))
return 0;
+ if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
+ // doesn't match because the wild pcode must be a bit skip
+ //fprintf(stderr," Failing match because bit skip is req:\n");
+ //pcd->print(stderr,pcd);
+ //pcs->print(stderr,pcs);
+ return 0;
+ }
+
+ if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) {
+ // doesn't match because the wild pcode must *not* be a bit skip
+ //fprintf(stderr," Failing match because don't want skip :\n");
+ //pcd->print(stderr,pcd);
+ //pcs->print(stderr,pcs);
+ return 0;
+ }
+
if(PCW(pcd)->operand) {
PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop;
- if(peepBlock->vars[index]) {
- int i = (strcmp(peepBlock->vars[index],PCI(pcs)->pcop->name) == 0);
+ if(peepBlock->target.vars[index]) {
+ int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0);
/*
if(i)
DFPRINTF((stderr," (matched)\n"));
*/
return i;
} else {
- peepBlock->vars[index] = PCI(pcs)->pcop->name;
+ peepBlock->target.vars[index] = PCI(pcs)->pcop->name;
return 1;
}
}
if(!pcp)
return;
- for(i=0;i<pcp->nvars; i++) {
- pcp->vars[i] = NULL;
- pcp->wildpCodeOps[i] = NULL;
+ for(i=0;i<pcp->target.nvars; i++) {
+ pcp->target.vars[i] = NULL;
+ pcp->target.wildpCodeOps[i] = NULL;
}
}
/*-----------------------------------------------------------------*/
/* pCodeOpCopy - copy a pcode operator */
/*-----------------------------------------------------------------*/
-static pCodeOp *pCodeOpCopy(pCodeOp *pcop)
+pCodeOp *pCodeOpCopy(pCodeOp *pcop)
{
pCodeOp *pcopnew=NULL;
else {
// Probably a label
pcopnew = pCodeOpCopy(PCOW(pcop)->subtype);
- pcopnew->name = Safe_strdup(PCOW(pcop)->pcp->vars[PCOW(pcop)->id]);
+ pcopnew->name = Safe_strdup(PCOW(pcop)->pcwb->vars[PCOW(pcop)->id]);
//DFPRINTF((stderr,"copied a wild op named %s\n",pcopnew->name));
}
PCOLAB(pcopnew)->key = PCOLAB(pcop)->key;
break;
- case PO_LITERAL:
case PO_IMMEDIATE:
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpImmd) );
+ PCOI(pcopnew)->offset = PCOI(pcop)->offset;
+ break;
+
+ case PO_LITERAL:
//DFPRINTF((stderr,"pCodeOpCopy lit\n"));
pcopnew = Safe_calloc(1,sizeof(pCodeOpLit) );
PCOL(pcopnew)->lit = PCOL(pcop)->lit;
DFPRINTF((stderr," register index %d\n", PCOR(pcop)->r->rIdx));
break;
+ case PO_DIR:
+ fprintf(stderr,"pCodeOpCopy PO_DIR\n");
+ pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
+ break;
case PO_STATUS:
DFPRINTF((stderr,"pCodeOpCopy PO_STATUS\n"));
- case PO_DIR:
- //DFPRINTF((stderr,"pCodeOpCopy PO_DIR\n"));
case PO_SFR_REGISTER:
case PO_STR:
case PO_NONE:
return pcopnew;
}
-#if 0
+
/*-----------------------------------------------------------------*/
/* pCodeCopy - copy a pcode */
/*-----------------------------------------------------------------*/
-static pCode *pCodeCopy(pCode *pc)
+static pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert)
{
+ pCodeInstruction *new_pci;
+
+ if(invert)
+ new_pci = PCI(newpCode(pci->inverted_op,pci->pcop));
+ else
+ new_pci = PCI(newpCode(pci->op,pci->pcop));
- pCode *pcnew;
+ new_pci->pc.pb = pci->pc.pb;
+ new_pci->from = pci->from;
+ new_pci->to = pci->to;
+ new_pci->label = pci->label;
+ new_pci->pcflow = pci->pcflow;
- pcnew = newpCode(pc->type,pc->pcop);
+ return PCODE(new_pci);
}
-#endif
+
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
void pCodeDeleteChain(pCode *f,pCode *t)
while(peeprules) {
peepBlock = ((pCodePeepSnippets*)peeprules)->peep;
- if(!peepBlock || !peepBlock->target || !peepBlock->target->pcHead)
+
+ if(!peepBlock || /*!peepBlock->target ||*/ !peepBlock->target.pb->pcHead) {
+ fprintf(stderr, "skipping rule because target pb is NULL\n");
goto next_rule;
+ }
pCodePeepClrVars(peepBlock);
pcin = pc;
- pct = peepBlock->target->pcHead;
+ if(IS_PCCOMMENT(pcin))
+ pc = pcin = findNextInstruction(pcin->next);
+
+ pct = peepBlock->target.pb->pcHead;
matched = 0;
while(pct && pcin) {
inefficient code with the optimized version */
#ifdef PCODE_DEBUG
DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
- printpCodeString(stderr,peepBlock->target->pcHead,10);
+ printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
DFPRINTF((stderr,"first thing matched\n"));
pc->print(stderr,pc);
#endif
/* Generate the replacement code */
pc = pcprev;
- pcr = peepBlock->replace->pcHead; // This is the replacement code
+ pcr = peepBlock->replace.pb->pcHead; // This is the replacement code
while (pcr) {
pCodeOp *pcop=NULL;
/* If the replace pcode is an instruction with an operand, */
if(PCI(pcr)->pcop->type == PO_WILD) {
int index = PCOW(PCI(pcr)->pcop)->id;
//DFPRINTF((stderr,"copying wildopcode\n"));
- if(peepBlock->wildpCodeOps[index])
- pcop = pCodeOpCopy(peepBlock->wildpCodeOps[index]);
+ if(peepBlock->target.wildpCodeOps[index])
+ pcop = pCodeOpCopy(peepBlock->target.wildpCodeOps[index]);
else
DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
} else
//DFPRINTF((stderr,"inserting pCode\n"));
pCodeInsertAfter(pc, newpCode(PCI(pcr)->op,pcop));
} else if (pcr->type == PC_WILD) {
- pCodeInsertAfter(pc,peepBlock->wildpCodes[PCW(pcr)->id]);
+ if(PCW(pcr)->invertBitSkipInst)
+ DFPRINTF((stderr,"We need to invert the bit skip instruction\n"));
+ pCodeInsertAfter(pc,
+ pCodeInstructionCopy(PCI(peepBlock->target.wildpCodes[PCW(pcr)->id]),
+ PCW(pcr)->invertBitSkipInst));
} else if (pcr->type == PC_COMMENT) {
pCodeInsertAfter(pc, newpCodeCharP( ((pCodeComment *)(pcr))->comment));
}
// is smart enough to look more than one instruction past the
// target block...
//
+// Special commands
+//
+//
+// _NOTBITSKIP_ %1 - Creates a wild card instruction that
+// will match all instructions except for
+// bit skip instructions (btfsc or btfss)
+// _BITSKIP_ %1 - Creates a wild card instruction that only
+// will match a bit skip instruction (btfsc
+// or btfss)
+// _INVERTBITSKIP_ %1 - For the wild card instruction %1, invert
+// the state of the bit skip. If %1 is not
+// a bit skip instruction, then there's an
+// error in the peep rule.
+//
+//
//
-replace restart {
- btfss %1
- goto %2
- %3
-%2: %4
-} by {
- ;peep 1 - test/jump to test/skip
- btfsc %1
- %3
-%2: %4
-}
+// Peep 1
+// Converts
+//
+// btfss reg1,bit
+// goto label
+// incf reg2,f
+//label
+//
+// Into:
+//
+// btfsc reg1,bit
+// incf reg2,f
+//label
+//
+// Notice that wild cards will allow any instruction
+// besides incf to be used in the above.
+//
+// Also, notice that this snippet is not valid if
+// it follows another skip
replace restart {
- btfsc %1
- goto %2
- %3
-%2: %4
+ _NOTBITSKIP_ %1
+ _BITSKIP_ %2
+ goto %3
+ %4
+%3: %5
} by {
- ;peep 1a - test/jump to test/skip
- btfss %1
- %3
-%2: %4
-}
+ ;peep 1 - test/jump to test/skip
+ %1
+ _INVERTBITSKIP_ %2
+ %4
+%3: %5
+}
replace restart {
- btfss %1
- goto %4
-%2: %3
+ _NOTBITSKIP_ %1
+ _BITSKIP_ %2
+ goto %3
%4: %5
+%3: %6
} by {
;peep 1b - test/jump to test/skip
- btfsc %1
-%2: %3
+ %1
+ _INVERTBITSKIP_ %2
%4: %5
-}
+%3: %6
+}
-replace restart {
- btfsc %1
- goto %4
-%2: %3
-%4: %5
-} by {
- ;peep 1c - test/jump to test/skip
- btfss %1
-%2: %3
-%4: %5
-}
+//replace restart {
+// btfss %1
+// goto %2
+// %3
+//%2: %4
+//} by {
+// ;peep 1 - test/jump to test/skip
+// btfsc %1
+// %3
+//%2: %4
+//}
+//
+//replace restart {
+// btfsc %1
+// goto %2
+// %3
+//%2: %4
+//} by {
+// ;peep 1a - test/jump to test/skip
+// btfss %1
+// %3
+//%2: %4
+//}
+//
+//replace restart {
+// btfss %1
+// goto %4
+//%2: %3
+//%4: %5
+//} by {
+// ;peep 1b - test/jump to test/skip
+// btfsc %1
+//%2: %3
+//%4: %5
+//}
+//
+//replace restart {
+// btfsc %1
+// goto %4
+//%2: %3
+//%4: %5
+//} by {
+// ;peep 1c - test/jump to test/skip
+// btfss %1
+//%2: %3
+//%4: %5
+//}
//bogus test for pcode
movf %1,w
movf %1,w
} by {
- ; peep 8 - Removed redundant move
+ ; peep 4 - Removed redundant move
movf %1,w
}
movwf %2
movlw %1
} by {
- ; peep 10 - Removed redundant move
+ ; peep 5 - Removed redundant move
movlw %1
movwf %2
}
movwf %1
movwf %1
} by {
- ; peep 11 - Removed redundant move
+ ; peep 6 - Removed redundant move
movwf %1
}
*buffer = 's';
dReg->name = Safe_strdup(buffer);
}
- //fprintf(stderr,"newReg: %s\n",dReg->name);
+ //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
dReg->isFree = 0;
dReg->wasUsed = 1;
dReg->isFixed = 0;
/* dirregWithName - search for register by name */
/*-----------------------------------------------------------------*/
regs *
-dirregWithName (char *name )
+dirregWithName (char *name)
{
int hkey;
regs *reg;
/* allocDirReg - allocates register of given type */
/*-----------------------------------------------------------------*/
regs *
-allocRegByName (char *name )
+allocRegByName (char *name, int size)
{
regs *reg;
* a new one and put it in the hash table AND in the
* dynDirectRegNames set */
- reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,1,0 );
+ reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
if((dReg = regFindFree(dynAllocRegs)) != NULL)
return dReg;
- return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,0,0));
+ return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
case REG_STK:
}
}
+/*-----------------------------------------------------------------*/
+/* rematStr - returns the rematerialized string for a remat var */
+/*-----------------------------------------------------------------*/
+static symbol *
+rematStr (symbol * sym)
+{
+ char *s = buffer;
+ iCode *ic = sym->rematiCode;
+ symbol *psym = NULL;
+
+ debugLog ("%s\n", __FUNCTION__);
+
+ printf ("%s\n", s);
+
+ /* if plus or minus print the right hand side */
+
+ if (ic->op == '+' || ic->op == '-') {
+
+ iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
+
+ sprintf (s, "(%s %c 0x%04x)",
+ OP_SYMBOL (IC_LEFT (ric))->rname,
+ ic->op,
+ (int) operandLitValue (IC_RIGHT (ic)));
+
+
+ fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
+
+ psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
+ psym->offset = (int) operandLitValue (IC_RIGHT (ic));
+
+ return psym;
+ }
+
+ sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
+ psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
+
+ printf ("%s\n", buffer);
+ return psym;
+}
+
+#if 0
/*-----------------------------------------------------------------*/
/* rematStr - returns the rematerialized string for a remat var */
/*-----------------------------------------------------------------*/
//s += strlen(s);
//ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
//continue ;
+ fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
return buffer;
}
printf ("%s\n", buffer);
return buffer;
}
+#endif
/*-----------------------------------------------------------------*/
/* regTypeNum - computes the type & number of registers required */
DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
/* create a psuedo symbol & force a spil */
- symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+ //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
+ symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
psym->type = sym->type;
psym->etype = sym->etype;
strcpy (psym->rname, psym->name);
regs *pic14_findFreeReg(short type);
regs *pic14_allocWithIdx (int idx);
regs *allocDirReg (operand *op );
-regs *allocRegByName (char *name );
+regs *allocRegByName (char *name, int size );
/* Define register address that are constant across PIC family */
#define IDX_INDF 0