From bfbab54dcff5c3613d548e106c8f726f94f32638 Mon Sep 17 00:00:00 2001 From: sdattalo Date: Fri, 10 May 2002 18:18:49 +0000 Subject: [PATCH] Added support for multiplication. Fixed peep hole bugs (and more functionality to the peep hole optimizer). Began weeding out AOP_XXX types for asm ops and am starting to replace with pcode types. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2013 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 3 + configure | 233 ++++++++++++++++----------- src/SDCCmain.c | 50 ++++-- src/pic/device.c | 49 +++--- src/pic/device.h | 2 +- src/pic/gen.c | 366 +++++++++++++++++++++++++++-------------- src/pic/gen.h | 10 +- src/pic/genarith.c | 241 +++++++++++++++++++++++++++ src/pic/main.c | 50 +++++- src/pic/pcode.c | 206 +++++++++++++++++++++--- src/pic/pcode.h | 100 +++++++++--- src/pic/pcodepeep.c | 385 +++++++++++++++++++++++++++++++++----------- src/pic/peeph.def | 143 +++++++++++----- src/pic/ralloc.c | 57 ++++++- src/pic/ralloc.h | 2 +- 15 files changed, 1469 insertions(+), 428 deletions(-) diff --git a/ChangeLog b/ChangeLog index a88814c7..69d11c3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2002-05-10 Scott Dattal + * src/pic/*: Added support for multiplication. Fixed many,many bugs. + 2002-04-22 Michael Hope * device/lib/z80/printf.c: Changed emitter to volatile to work around a pcall bug. diff --git a/configure b/configure index ca471bb7..1260fe0a 100755 --- a/configure +++ b/configure @@ -545,7 +545,7 @@ fi -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 @@ -1007,8 +1007,59 @@ else fi fi +for ac_declaration in \ + ''\ + '#include ' \ + '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 < +$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 <&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= @@ -1023,13 +1074,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < 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 : @@ -1040,13 +1091,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < 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 : @@ -1057,13 +1108,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < 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 : @@ -1118,7 +1169,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # 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 @@ -1173,7 +1224,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # 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 @@ -1203,7 +1254,7 @@ fi # 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 @@ -1237,7 +1288,7 @@ then *) 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 @@ -1245,7 +1296,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&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 @@ -1281,7 +1332,7 @@ fi # 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 @@ -1311,7 +1362,7 @@ fi # 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 @@ -1341,7 +1392,7 @@ fi # 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 @@ -1371,7 +1422,7 @@ fi # 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 @@ -1401,7 +1452,7 @@ fi # 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 @@ -1451,12 +1502,12 @@ cross_compiling=$ac_cv_prog_cc_cross # 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 < #include @@ -1464,7 +1515,7 @@ else #include 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* @@ -1481,7 +1532,7 @@ rm -f 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 @@ -1499,7 +1550,7 @@ fi 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 @@ -1520,7 +1571,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1531,7 +1582,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); 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 @@ -1558,17 +1609,17 @@ for ac_hdr in getopt.h 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 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* @@ -1598,17 +1649,17 @@ for ac_hdr in unistd.h 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 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* @@ -1638,17 +1689,17 @@ for ac_hdr in endian.h 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 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* @@ -1678,17 +1729,17 @@ for ac_hdr in machine/endian.h 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 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* @@ -1718,17 +1769,17 @@ for ac_hdr in malloc.h 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 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* @@ -1758,17 +1809,17 @@ for ac_hdr in sys/isa_defs.h 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 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* @@ -1798,17 +1849,17 @@ for ac_hdr in sys/socket.h 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 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* @@ -1839,12 +1890,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h 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 < #include <$ac_hdr> @@ -1852,7 +1903,7 @@ int main() { 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 @@ -1877,7 +1928,7 @@ done # 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 @@ -1885,7 +1936,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&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 @@ -1918,7 +1969,7 @@ fi 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 @@ -1926,7 +1977,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&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 @@ -1963,13 +2014,13 @@ fi # 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 < @@ -1985,7 +2036,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < @@ -2001,7 +2052,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < @@ -2081,12 +2132,12 @@ EOF 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 <&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 @@ -2136,12 +2187,12 @@ done 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 <&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 @@ -2191,12 +2242,12 @@ done 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 <&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 @@ -2246,12 +2297,12 @@ done 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 <&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 @@ -2302,14 +2353,14 @@ done # 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 <&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 @@ -2331,7 +2382,7 @@ rm -f conftest* test "$ac_cv_search_socket" = "no" && for i in socket; do LIBS="-l$i $ac_func_search_save_LIBS" cat > conftest.$ac_ext <&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 @@ -2364,14 +2415,14 @@ else : 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 <&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 @@ -2393,7 +2444,7 @@ rm -f conftest* 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 <&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 @@ -2438,7 +2489,7 @@ fi # 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 @@ -2460,7 +2511,7 @@ M_OR_MM=$sdcc_cv_MM # 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 @@ -2485,7 +2536,7 @@ fi 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 @@ -2512,12 +2563,12 @@ fi # 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 < #include @@ -2534,7 +2585,7 @@ int main() { 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 @@ -2823,7 +2874,7 @@ fi 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 @@ -2831,7 +2882,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgc $LIBS" cat > conftest.$ac_ext <&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 diff --git a/src/SDCCmain.c b/src/SDCCmain.c index c1510d14..c01f1758 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -294,6 +294,15 @@ _setPort (const char *name) 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) { @@ -330,6 +339,23 @@ _findPort (int argc, char **argv) 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 */ /*-----------------------------------------------------------------*/ @@ -597,13 +623,6 @@ _setModel (int model, const char *sz) 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. */ @@ -966,13 +985,12 @@ parseCmdLine (int argc, char **argv) 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': @@ -1542,7 +1560,14 @@ main (int argc, char **argv, char **envp) 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"); @@ -1550,6 +1575,9 @@ main (int argc, char **argv, char **envp) ds390_jammed = 1; } #endif + + _findProcessor (argc, argv); + /* Initalise the port. */ if (port->init) port->init (); diff --git a/src/pic/device.c b/src/pic/device.c index a7d546f4..db4e2b39 100644 --- a/src/pic/device.c +++ b/src/pic/device.c @@ -146,7 +146,7 @@ static PIC_device Pics[] = { }; 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; @@ -171,7 +171,7 @@ static void addMem(memRange *ranges,int type) 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; @@ -210,12 +210,12 @@ static void addMaps(PIC_device *pPic) /* 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++; @@ -223,11 +223,11 @@ static void addMaps(PIC_device *pPic) - 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; } @@ -245,7 +245,7 @@ void dump_map(void) { 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) { @@ -309,7 +309,7 @@ void dump_cblock(FILE *of) addr++; - } while(addr <= pic->max_address); + } while(addr <= pic->maxRAMaddress); } @@ -332,7 +332,6 @@ void list_valid_pics(int ncols, int list_alias) 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; @@ -397,12 +396,18 @@ PIC_device *find_device(char *name) /*-----------------------------------------------------------------* * *-----------------------------------------------------------------*/ -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); } @@ -428,7 +433,7 @@ char *processor_base_name(void) int isSFR(int address) { - if( (address > pic->max_address) || !finalMapping[address].isSFR) + if( (address > pic->maxRAMaddress) || !finalMapping[address].isSFR) return 0; return 1; @@ -439,7 +444,7 @@ int validAddress(int address, int reg_size) { int i; - if(address > pic->max_address) + if(address > pic->maxRAMaddress) return 0; for (i=0; isize) { + fprintf(stderr,"WARNING: %s:%s:%d Bad register\n",__FILE__,__FUNCTION__,__LINE__); + return; + } for(i=0; isize; i++) { @@ -466,7 +474,7 @@ void mapRegister(regs *reg) 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; @@ -480,6 +488,8 @@ void mapRegister(regs *reg) } while (alias>=0); } + // fprintf(stderr,"%s - %s addr = 0x%03x, size %d\n",__FUNCTION__,reg->name, reg->address,reg->size); + reg->isMapped = 1; } @@ -488,6 +498,7 @@ int assignRegister(regs *reg, int start_address) { 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)) { @@ -509,7 +520,7 @@ int assignRegister(regs *reg, int start_address) * 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; @@ -547,7 +558,7 @@ void assignRelocatableRegisters(set *regset, int used) 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); diff --git a/src/pic/device.h b/src/pic/device.h index 1dc4c0c1..c4ff2f33 100644 --- a/src/pic/device.h +++ b/src/pic/device.h @@ -79,7 +79,7 @@ typedef struct PIC_device { 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; diff --git a/src/pic/gen.c b/src/pic/gen.c index 08537ea7..409435d4 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -60,6 +60,10 @@ #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; @@ -71,6 +75,7 @@ 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 ); @@ -170,6 +175,20 @@ void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *res } +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; @@ -205,7 +224,7 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...) } -static void emitpLabel(int key) +void emitpLabel(int key) { addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset)); } @@ -545,33 +564,42 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) 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; } @@ -765,6 +793,7 @@ void aopOp (operand *op, iCode *ic, bool result) 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; } @@ -793,10 +822,16 @@ void aopOp (operand *op, iCode *ic, bool result) /* 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; } @@ -1011,11 +1046,12 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname) 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); @@ -1050,6 +1086,22 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname) 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__, @@ -1057,6 +1109,34 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname) 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 */ /*-----------------------------------------------------------------*/ @@ -1080,8 +1160,12 @@ pCodeOp *popCopyReg(pCodeOpReg *pc) 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; @@ -1164,7 +1248,7 @@ pCodeOp *popRegFromIdx(int rIdx) /*-----------------------------------------------------------------*/ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) { - char *s = buffer ; + //char *s = buffer ; //char *rs; pCodeOp *pcop; @@ -1196,6 +1280,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); pcop->type = PO_DIR; + /* if (offset) sprintf(s,"(%s + %d)", aop->aopu.aop_dir, @@ -1204,11 +1289,17 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) 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; @@ -1248,6 +1339,10 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) return pcop; */ + + case AOP_PCODE: + DEBUGpic14_emitcode(";","popGet AOP_PCODE%d",__LINE__); + return pCodeOpCopy(aop->aopu.pcop); } werror(E_INTERNAL_ERROR,__FILE__,__LINE__, @@ -1274,10 +1369,12 @@ void aopPut (asmop *aop, char *s, int offset) /* 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)) { @@ -2441,13 +2538,13 @@ static int resultRemat (iCode *ic) #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__); @@ -2460,9 +2557,9 @@ static bool inExcludeList(char *s) STRCASECMP(s,options.excludeRegs[i]) == 0) return TRUE; } -#endif return FALSE ; } +#endif /*-----------------------------------------------------------------*/ /* genFunction - generated code for function entry */ @@ -2931,85 +3028,103 @@ static void genMultOneByte (operand *left, 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++); + } } /*-----------------------------------------------------------------*/ @@ -3044,8 +3159,10 @@ static void genMult (iCode *ic) 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)); @@ -7436,6 +7553,8 @@ static void genDataPointerGet (operand *left, aopOp(result,ic,TRUE); + DEBUGpic14_AopType(__LINE__,left,NULL,result); + emitpcode(POC_MOVFW, popGet(AOP(left),0)); size = AOP_SIZE(result); @@ -7474,10 +7593,10 @@ static void genNearPointerGet (operand *left, 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 ; } @@ -7792,7 +7911,7 @@ static void genGenPointerGet (operand *left, 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; @@ -8082,12 +8201,19 @@ static void genDataPointerSet(operand *right, 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); @@ -8097,19 +8223,21 @@ static void genDataPointerSet(operand *right, 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)); } @@ -8140,8 +8268,9 @@ static void genNearPointerSet (operand *right, /* 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; @@ -9358,6 +9487,9 @@ void genpic14Code (iCode *lic) _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 diff --git a/src/pic/gen.h b/src/pic/gen.h index f262de7a..f256aa72 100644 --- a/src/pic/gen.h +++ b/src/pic/gen.h @@ -26,13 +26,17 @@ #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 @@ -70,6 +74,7 @@ typedef struct asmop 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; } @@ -135,6 +140,7 @@ extern unsigned fReturnSizePic; 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); @@ -159,6 +165,8 @@ pCodeOp *popGetLit(unsigned int lit); 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); diff --git a/src/pic/genarith.c b/src/pic/genarith.c index 832fa55f..1741ad97 100644 --- a/src/pic/genarith.c +++ b/src/pic/genarith.c @@ -106,6 +106,9 @@ const char *AopType(short type) case AOP_ACC: return "AOP_ACC"; break; + case AOP_PCODE: + return "AOP_PCODE"; + break; } return "BAD TYPE"; @@ -1473,5 +1476,243 @@ void genMinus (iCode *ic) 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<>= 1; + + } + +} + +#endif diff --git a/src/pic/main.c b/src/pic/main.c index dd41e64c..cec44669 100644 --- a/src/pic/main.c +++ b/src/pic/main.c @@ -207,6 +207,50 @@ _pic14_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts) 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 @@ -234,7 +278,7 @@ PORT pic_port = TARGET_ID_PIC, "pic14", "MCU pic", /* Target name */ - NULL, /* Processor */ + "p16f877", /* Processor */ { TRUE, /* Emit glue around main */ MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24, @@ -285,7 +329,7 @@ PORT pic_port = NULL, // xinit NULL, NULL, - 1 + 1 // code is read only }, { +1, 1, 4, 1, 1, 0 @@ -311,7 +355,7 @@ PORT pic_port = _pic14_regparm, NULL, NULL, - NULL, + _hasNativeMulFor, FALSE, 0, /* leave lt */ 0, /* leave gt */ diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 98113546..78d97b78 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -35,6 +35,19 @@ #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}; @@ -52,17 +65,19 @@ static int mnemonics_initialized = 0; 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)) @@ -107,6 +122,7 @@ pCodeInstruction pciADDWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond }; @@ -116,7 +132,7 @@ pCodeInstruction pciADDFW = { // genericAnalyze, genericDestruct, genericPrint}, - POC_ADDWF, + POC_ADDFW, "ADDWF", NULL, // from branch NULL, // to branch @@ -126,6 +142,7 @@ pCodeInstruction pciADDFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond }; @@ -145,6 +162,7 @@ pCodeInstruction pciADDLW = { 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 }; @@ -164,6 +182,7 @@ pCodeInstruction pciANDLW = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_W, // inCond (PCC_W | PCC_Z) // outCond }; @@ -183,6 +202,7 @@ pCodeInstruction pciANDWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond }; @@ -192,7 +212,7 @@ pCodeInstruction pciANDFW = { // genericAnalyze, genericDestruct, genericPrint}, - POC_ANDWF, + POC_ANDFW, "ANDWF", NULL, // from branch NULL, // to branch @@ -202,6 +222,7 @@ pCodeInstruction pciANDFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond }; @@ -221,6 +242,7 @@ pCodeInstruction pciBCF = { 2, // num ops 1,1, // dest, bit instruction 0,0, // branch, skip + POC_BSF, PCC_REGISTER, // inCond PCC_REGISTER // outCond }; @@ -240,6 +262,7 @@ pCodeInstruction pciBSF = { 2, // num ops 1,1, // dest, bit instruction 0,0, // branch, skip + POC_BCF, PCC_REGISTER, // inCond PCC_REGISTER // outCond }; @@ -259,6 +282,7 @@ pCodeInstruction pciBTFSC = { 2, // num ops 0,1, // dest, bit instruction 1,1, // branch, skip + POC_BTFSS, PCC_REGISTER, // inCond PCC_NONE // outCond }; @@ -278,6 +302,7 @@ pCodeInstruction pciBTFSS = { 2, // num ops 0,1, // dest, bit instruction 1,1, // branch, skip + POC_BTFSC, PCC_REGISTER, // inCond PCC_NONE // outCond }; @@ -297,6 +322,7 @@ pCodeInstruction pciCALL = { 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond }; @@ -316,6 +342,7 @@ pCodeInstruction pciCOMF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond }; @@ -335,6 +362,7 @@ pCodeInstruction pciCOMFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond }; @@ -354,6 +382,7 @@ pCodeInstruction pciCLRF = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond }; @@ -373,6 +402,7 @@ pCodeInstruction pciCLRW = { 0, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_W, // inCond PCC_W // outCond }; @@ -392,6 +422,7 @@ pCodeInstruction pciDECF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond }; @@ -411,6 +442,7 @@ pCodeInstruction pciDECFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond }; @@ -430,6 +462,7 @@ pCodeInstruction pciDECFSZ = { 2, // num ops 1,0, // dest, bit instruction 1,1, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond }; @@ -449,6 +482,7 @@ pCodeInstruction pciDECFSZW = { 2, // num ops 0,0, // dest, bit instruction 1,1, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond }; @@ -468,11 +502,11 @@ pCodeInstruction pciGOTO = { 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, @@ -488,6 +522,7 @@ pCodeInstruction pciINCF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond }; @@ -507,6 +542,7 @@ pCodeInstruction pciINCFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond }; @@ -526,6 +562,7 @@ pCodeInstruction pciINCFSZ = { 2, // num ops 1,0, // dest, bit instruction 1,1, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_REGISTER // outCond }; @@ -545,6 +582,7 @@ pCodeInstruction pciINCFSZW = { 2, // num ops 0,0, // dest, bit instruction 1,1, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_W // outCond }; @@ -564,6 +602,7 @@ pCodeInstruction pciIORWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond }; @@ -573,7 +612,7 @@ pCodeInstruction pciIORFW = { // genericAnalyze, genericDestruct, genericPrint}, - POC_IORWF, + POC_IORFW, "IORWF", NULL, // from branch NULL, // to branch @@ -583,6 +622,7 @@ pCodeInstruction pciIORFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond }; @@ -602,6 +642,7 @@ pCodeInstruction pciIORLW = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_W, // inCond (PCC_W | PCC_Z) // outCond }; @@ -621,6 +662,7 @@ pCodeInstruction pciMOVF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_REGISTER, // inCond PCC_Z // outCond }; @@ -640,6 +682,7 @@ pCodeInstruction pciMOVFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_REGISTER, // inCond (PCC_W | PCC_Z) // outCond }; @@ -659,6 +702,7 @@ pCodeInstruction pciMOVWF = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_W, // inCond PCC_REGISTER // outCond }; @@ -678,6 +722,7 @@ pCodeInstruction pciMOVLW = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_NONE, // inCond PCC_W // outCond }; @@ -696,6 +741,7 @@ pCodeInstruction pciNOP = { 0, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond }; @@ -715,6 +761,7 @@ pCodeInstruction pciRETFIE = { 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) }; @@ -734,6 +781,7 @@ pCodeInstruction pciRETLW = { 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + POC_NOP, PCC_NONE, // inCond PCC_W // outCond }; @@ -753,6 +801,7 @@ pCodeInstruction pciRETURN = { 0, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip + POC_NOP, PCC_NONE, // inCond PCC_NONE // outCond }; @@ -772,6 +821,7 @@ pCodeInstruction pciRLF = { 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 }; @@ -791,6 +841,7 @@ pCodeInstruction pciRLFW = { 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 }; @@ -810,6 +861,7 @@ pCodeInstruction pciRRF = { 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 }; @@ -829,6 +881,7 @@ pCodeInstruction pciRRFW = { 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 }; @@ -848,6 +901,7 @@ pCodeInstruction pciSUBWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond }; @@ -857,7 +911,7 @@ pCodeInstruction pciSUBFW = { // genericAnalyze, genericDestruct, genericPrint}, - POC_SUBWF, + POC_SUBFW, "SUBWF", NULL, // from branch NULL, // to branch @@ -867,6 +921,7 @@ pCodeInstruction pciSUBFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond }; @@ -886,6 +941,7 @@ pCodeInstruction pciSUBLW = { 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 }; @@ -905,6 +961,7 @@ pCodeInstruction pciSWAPF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_REGISTER), // inCond (PCC_REGISTER) // outCond }; @@ -924,6 +981,7 @@ pCodeInstruction pciSWAPFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_REGISTER), // inCond (PCC_W) // outCond }; @@ -943,6 +1001,7 @@ pCodeInstruction pciTRIS = { 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, PCC_NONE, // inCond PCC_REGISTER // outCond }; @@ -962,6 +1021,7 @@ pCodeInstruction pciXORWF = { 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_REGISTER | PCC_Z) // outCond }; @@ -971,7 +1031,7 @@ pCodeInstruction pciXORFW = { // genericAnalyze, genericDestruct, genericPrint}, - POC_XORWF, + POC_XORFW, "XORWF", NULL, // from branch NULL, // to branch @@ -981,6 +1041,7 @@ pCodeInstruction pciXORFW = { 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip + POC_NOP, (PCC_W | PCC_REGISTER), // inCond (PCC_W | PCC_Z) // outCond }; @@ -1000,6 +1061,7 @@ pCodeInstruction pciXORLW = { 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 }; @@ -1080,13 +1142,13 @@ void SAFE_snprintf(char **str, size_t *size, const char *format, ...) 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); @@ -1145,6 +1207,9 @@ void pic14initMnemonics(void) 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; @@ -1207,6 +1272,8 @@ void pic14initMnemonics(void) mnemonics_initialized = 1; } +int getpCodePeepCommand(char *cmd); + int getpCode(char *mnem,unsigned dest) { @@ -1232,6 +1299,59 @@ 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) @@ -1463,6 +1583,10 @@ pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_la pcw->operand = optional_operand; pcw->label = optional_label; + pcw->mustBeBitSkipInst = 0; + pcw->mustNotBeBitSkipInst = 0; + pcw->invertBitSkipInst = 0; + return ( (pCode *)pcw); } @@ -1722,11 +1846,11 @@ pCodeOp *newpCodeOpImmd(char *name, int offset) { 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; } @@ -1739,13 +1863,13 @@ pCodeOp *newpCodeOpImmd(char *name, int offset) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -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); } @@ -1756,7 +1880,7 @@ pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype) 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; @@ -1782,6 +1906,14 @@ pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace) 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; @@ -1789,18 +1921,29 @@ pCodeOp *newpCodeOpReg(int rIdx) 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; @@ -1828,6 +1971,9 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type) case PO_LABEL: pcop = newpCodeOpLabel(NULL,-1); break; + case PO_GPR_TEMP: + pcop = newpCodeOpReg(-1); + break; default: pcop = Safe_calloc(1,sizeof(pCodeOp) ); @@ -2044,14 +2190,35 @@ static char *get_op( pCodeInstruction *pcc) 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: @@ -3163,8 +3330,9 @@ void OptimizepCode(char dbName) } /*-----------------------------------------------------------------*/ -/* popCopy - copy a pcode operator */ +/* popCopyGPR2Bit - copy a pcode operator */ /*-----------------------------------------------------------------*/ + pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval) { pCodeOp *pcop; @@ -3437,7 +3605,7 @@ void buildCallTree(void ) 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'; } diff --git a/src/pic/pcode.h b/src/pic/pcode.h index 8a8df94f..9e1d0033 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -76,7 +76,7 @@ struct regs; * The double parenthesis (()) are necessary * ***********************************************************************/ -#define PCODE_DEBUG +//#define PCODE_DEBUG #ifdef PCODE_DEBUG #define DFPRINTF(args) (fprintf args) @@ -240,6 +240,7 @@ typedef enum /*************** Structures ********************/ /************************************************/ struct pCode; +struct pCodeWildBlock; /************************************************* pBranch @@ -331,6 +332,22 @@ typedef struct pCodeOpRegBit } 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 @@ -440,6 +457,7 @@ typedef struct pCodeInstruction 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 @@ -495,6 +513,10 @@ typedef struct pCodeWild * - 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 @@ -555,6 +577,28 @@ typedef struct pFile +/************************************************* + 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 @@ -567,17 +611,12 @@ typedef struct pFile 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 @@ -595,19 +634,32 @@ typedef struct pCodePeep { } 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 @@ -631,6 +683,8 @@ typedef struct pCodeOpWild #define PBR(x) ((pBranch *)(x)) +#define PCWB(x) ((pCodeWildBlock *)(x)) + /*-----------------------------------------------------------------* * pCode functions. *-----------------------------------------------------------------*/ @@ -658,6 +712,8 @@ pCodeOp *newpCodeOpLit(int lit); 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); /*-----------------------------------------------------------------* diff --git a/src/pic/pcodepeep.c b/src/pic/pcodepeep.c index 8e7dcdb4..6db8ae9a 100644 --- a/src/pic/pcodepeep.c +++ b/src/pic/pcodepeep.c @@ -38,16 +38,19 @@ 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 @@ -90,7 +93,7 @@ static pCodePeepSnippets *peepSnippets=NULL; /* */ /****************************************************************/ -static pCodePeep *curPeep=NULL; +//static pCodePeep *curPeep=NULL; /****************************************************************/ /* */ @@ -98,7 +101,7 @@ static pCodePeep *curPeep=NULL; /* */ /****************************************************************/ -static pBlock *curBlock=NULL; +//static pBlock *curBlock=NULL; /****************************************************************/ @@ -107,8 +110,8 @@ static pBlock *curBlock=NULL; /* */ /****************************************************************/ -static int sMaxWildVar = 0; -static int sMaxWildMnem = 0; +//static int sMaxWildVar = 0; +//static int sMaxWildMnem = 0; typedef struct pCodeToken @@ -130,6 +133,8 @@ typedef enum { PCT_NULL=0, PCT_SPACE=1, PCT_PERCENT, + PCT_LESSTHAN, + PCT_GREATERTHAN, PCT_COLON, PCT_COMMA, PCT_COMMENT, @@ -171,7 +176,7 @@ static char pcpat_comment[] = {PCT_COMMENT, 0}; 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[] = { @@ -209,15 +214,15 @@ static char alt_mnem1b[] = { PCP_STR, PCP_NUMBER, 0}; 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}, @@ -304,7 +309,7 @@ static pCodeOp *cvt_extract_status(char *reg, char *bit) /* 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; @@ -321,7 +326,7 @@ static void * cvt_altpat_label(void *pp) /* */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_comment(void *pp) +static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; @@ -331,8 +336,13 @@ static void * cvt_altpat_comment(void *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; @@ -342,8 +352,15 @@ static void * cvt_altpat_mnem0(void *pp) 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; } @@ -363,7 +380,7 @@ static void * cvt_altpat_mnem0(void *pp) /* pp[0] - wild var */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem0a(void *pp) +static void * cvt_altpat_mnem0a(void *pp, pCodeWildBlock *pcwb) { parsedPattern *p = pp; @@ -371,8 +388,11 @@ static void * cvt_altpat_mnem0a(void *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); @@ -386,7 +406,7 @@ static void * cvt_altpat_mnem0a(void *pp) /* pp[1] - Operand */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem1(void *pp) +static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; @@ -399,7 +419,11 @@ static void * cvt_altpat_mnem1(void *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; } @@ -426,7 +450,7 @@ static void * cvt_altpat_mnem1(void *pp) /* 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; @@ -438,8 +462,30 @@ static void * cvt_altpat_mnem1a(void *pp) 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) @@ -449,11 +495,14 @@ static void * cvt_altpat_mnem1a(void *pp) 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"); @@ -464,7 +513,7 @@ static void * cvt_altpat_mnem1a(void *pp) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem1b(void *pp) +static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; int opcode; @@ -490,7 +539,7 @@ static void * cvt_altpat_mnem1b(void *pp) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem2(void *pp) +static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; int opcode; @@ -545,7 +594,7 @@ static void * cvt_altpat_mnem2(void *pp) /* pp[3] - destination */ /* */ /*-----------------------------------------------------------------*/ -static void * cvt_altpat_mnem2a(void *pp) +static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb) { parsedPattern *p = pp; int opcode; @@ -576,11 +625,14 @@ static void * cvt_altpat_mnem2a(void *pp) 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"); @@ -638,6 +690,12 @@ static void tokenizeLineNode(char *ln) 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; @@ -652,11 +710,11 @@ static void tokenizeLineNode(char *ln) 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--; @@ -695,12 +753,16 @@ void dump1Token(pCodeTokens tt) 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 , "); @@ -825,7 +887,7 @@ int advTokIdx(int *v, int amt) /* pcode. */ /*-----------------------------------------------------------------*/ -void parseTokens(void) +void parseTokens(pCodeWildBlock *pcwb) { unsigned i; pCode *pc; @@ -997,12 +1059,14 @@ void parseTokens(void) 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; } @@ -1032,7 +1096,7 @@ void parseTokens(void) /*-----------------------------------------------------------------*/ /* */ /*-----------------------------------------------------------------*/ -void peepRuleBlock2pCodeBlock( lineNode *ln) +void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb) { if(!ln) @@ -1043,7 +1107,7 @@ void peepRuleBlock2pCodeBlock( lineNode *ln) //DFPRINTF((stderr,"%s\n",ln->line)); tokenizeLineNode(ln->line); - parseTokens(); + parseTokens(pcwb); } } @@ -1051,22 +1115,74 @@ void peepRuleBlock2pCodeBlock( lineNode *ln) /*-----------------------------------------------------------------*/ /* 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. */ @@ -1078,13 +1194,17 @@ static void peepRuleCondition(char *cond) /* 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 */ @@ -1098,6 +1218,9 @@ void peepRules2pCode(peepRule *rules) //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; @@ -1105,44 +1228,50 @@ void peepRules2pCode(peepRule *rules) 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 *)); @@ -1152,11 +1281,27 @@ void peepRules2pCode(peepRule *rules) 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) @@ -1274,12 +1419,12 @@ int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) 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; } @@ -1327,6 +1472,9 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) { 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) { @@ -1357,8 +1505,8 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) } #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) @@ -1377,11 +1525,11 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) 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; } } @@ -1394,6 +1542,7 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) } } + /* Compare a wild instruction to a regular one. */ if((pcd->type == PC_WILD) && (pcs->type == PC_OPCODE)) { @@ -1404,15 +1553,31 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) //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")); @@ -1425,7 +1590,7 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) */ return i; } else { - peepBlock->vars[index] = PCI(pcs)->pcop->name; + peepBlock->target.vars[index] = PCI(pcs)->pcop->name; return 1; } } @@ -1454,9 +1619,9 @@ void pCodePeepClrVars(pCodePeep *pcp) if(!pcp) return; - for(i=0;invars; i++) { - pcp->vars[i] = NULL; - pcp->wildpCodeOps[i] = NULL; + for(i=0;itarget.nvars; i++) { + pcp->target.vars[i] = NULL; + pcp->target.wildpCodeOps[i] = NULL; } } @@ -1483,7 +1648,7 @@ void pCodeInsertAfter(pCode *pc1, pCode *pc2) /*-----------------------------------------------------------------*/ /* pCodeOpCopy - copy a pcode operator */ /*-----------------------------------------------------------------*/ -static pCodeOp *pCodeOpCopy(pCodeOp *pcop) +pCodeOp *pCodeOpCopy(pCodeOp *pcop) { pCodeOp *pcopnew=NULL; @@ -1509,7 +1674,7 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop) 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)); } @@ -1522,8 +1687,12 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop) 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; @@ -1549,10 +1718,12 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop) 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: @@ -1575,18 +1746,28 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop) 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) @@ -1618,13 +1799,19 @@ int pCodePeepMatchRule(pCode *pc) 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) { @@ -1667,7 +1854,7 @@ int pCodePeepMatchRule(pCode *pc) 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 @@ -1704,7 +1891,7 @@ int pCodePeepMatchRule(pCode *pc) /* 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, */ @@ -1716,8 +1903,8 @@ int pCodePeepMatchRule(pCode *pc) 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 @@ -1726,7 +1913,11 @@ int pCodePeepMatchRule(pCode *pc) //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)); } diff --git a/src/pic/peeph.def b/src/pic/peeph.def index bb586cc7..e48e6d0d 100644 --- a/src/pic/peeph.def +++ b/src/pic/peeph.def @@ -67,56 +67,119 @@ // 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 @@ -162,7 +225,7 @@ replace restart { movf %1,w movf %1,w } by { - ; peep 8 - Removed redundant move + ; peep 4 - Removed redundant move movf %1,w } @@ -172,7 +235,7 @@ replace restart { movwf %2 movlw %1 } by { - ; peep 10 - Removed redundant move + ; peep 5 - Removed redundant move movlw %1 movwf %2 } @@ -181,6 +244,6 @@ replace restart { movwf %1 movwf %1 } by { - ; peep 11 - Removed redundant move + ; peep 6 - Removed redundant move movwf %1 } diff --git a/src/pic/ralloc.c b/src/pic/ralloc.c index 19faff94..06e03638 100644 --- a/src/pic/ralloc.c +++ b/src/pic/ralloc.c @@ -430,7 +430,7 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i *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; @@ -548,7 +548,7 @@ static int regname2key(char const *name) /* dirregWithName - search for register by name */ /*-----------------------------------------------------------------*/ regs * -dirregWithName (char *name ) +dirregWithName (char *name) { int hkey; regs *reg; @@ -654,7 +654,7 @@ allocDirReg (operand *op ) /* allocDirReg - allocates register of given type */ /*-----------------------------------------------------------------*/ regs * -allocRegByName (char *name ) +allocRegByName (char *name, int size) { regs *reg; @@ -675,7 +675,7 @@ allocRegByName (char *name ) * 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); @@ -792,7 +792,7 @@ pic14_findFreeReg(short type) 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: @@ -2232,6 +2232,48 @@ createRegMask (eBBlock ** ebbs, int count) } } +/*-----------------------------------------------------------------*/ +/* 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 */ /*-----------------------------------------------------------------*/ @@ -2267,6 +2309,7 @@ rematStr (symbol * sym) //s += strlen(s); //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; //continue ; + fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s); return buffer; } @@ -2278,6 +2321,7 @@ rematStr (symbol * sym) printf ("%s\n", buffer); return buffer; } +#endif /*-----------------------------------------------------------------*/ /* regTypeNum - computes the type & number of registers required */ @@ -2340,7 +2384,8 @@ regTypeNum () 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); diff --git a/src/pic/ralloc.h b/src/pic/ralloc.h index ee2ee714..f8af1de2 100644 --- a/src/pic/ralloc.h +++ b/src/pic/ralloc.h @@ -81,7 +81,7 @@ void pic14_deallocateAllRegs (); 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 -- 2.30.2