Initial revision
authorTom Wood <wood@gnu.org>
Fri, 3 Jan 1992 13:43:25 +0000 (13:43 +0000)
committerTom Wood <wood@gnu.org>
Fri, 3 Jan 1992 13:43:25 +0000 (13:43 +0000)
From-SVN: r156

gcc/config/m88k/m88k-move.sh [new file with mode: 0755]

diff --git a/gcc/config/m88k/m88k-move.sh b/gcc/config/m88k/m88k-move.sh
new file mode 100755 (executable)
index 0000000..ee139a2
--- /dev/null
@@ -0,0 +1,300 @@
+#!/bin/sh
+#
+#      If your shell doesn't support functions (true for some BSD users),
+#      you might try using GNU's bash.
+#
+#ident "@(#) movstr-m88k.sh 17-Oct-90"
+#
+#      This file provided by Data General, Feburary 1990.
+#
+#      This script generates the necessary movstr library functions
+#      for the m88000.  These functions are called from the expansion
+#      of movstrsi.  There are eight modules created by this script,
+#      each with multiple entry points.  One module, movstrSI64n
+#      implements a word aligned loop; the other modules, movstrXINx
+#      implement a straight line copy of N bytes in mode XI.
+#
+#      By analysis of the best memcpy function, it can be determined
+#      what appear to be certain magic numbers.  For example, a
+#      memcpy of 13 bytes, where the pointers are determined at run
+#      time to be word aligned takes 28 cycles.  A call to
+#      __movstrQI13x13 also takes 28 cycles.  The break even point
+#      for a HImode copy is 38 bytes.  Just to be on the safe side,
+#      these are bumped to 16 and 48 respectively.
+#
+#      The smaller, odd-remainder modules are provided to help
+#      mitigate the overhead of copying the last bytes.
+#
+#      Changes to these functions should not be taken lightly if you
+#      want to be able to link programs built with older movstr
+#      parameters.  For this reason, Makefile regards movstr*.s as
+#      source modules and does not have a rule for creating them
+#      automatically.
+#
+#.Revision History
+#
+#      26-Oct-90   Tom Wood   Delete movstr.h; moved to out-m88k.c.
+#      17-Oct-90   Tom Wood   Files are named *.asm rather than *.s.
+#      11-Sep-90   Jeffrey Friedl
+#                      On my BSD 4.3 awk and my GNU-awk, only the
+#                      first character of an argument to -F is passed
+#                      through, so I can't get this to work.
+#       5-Sep-90   Ray Essick/Tom Wood  
+#                      Added a -no-tdesc option.
+#      27-Aug-90   Vince Guarna/Tom Wood   
+#                      Version 3 assembler syntax (-abi).
+#      16-Aug-90   Ron Guilmette
+#                      Avoid problems on a Sparc.  The common
+#                      denominator among shells seems to be '...\'
+#                      rather than '...\\'.
+#      15-Aug-90   Ron Guilmette
+#                      Avoid awk syntax errors on a Sun by not using
+#                      the `!' operator.
+#      22-Feb-90   Tom Wood    Created.
+#      20-Jun-90   Tom Wood    Emit file directives.
+#
+#.End]=--------------------------------------------------------------*/
+
+usage() {
+    echo "usage: $0 [ -abi ] [ -no-tdesc ]" 1>&2
+    exit 1
+}
+
+awk_flag="-F:";
+awk_begin="BEGIN { "
+do_file() {
+    echo "     file     $1";
+}
+
+while [ $# -gt 0 ] ; do
+    case $1 in
+       -no-tdesc) awk_begin="$awk_begin no_tdesc=1;";;
+       -abi) awk_begin="$awk_begin abi=1;"
+             do_file() {
+               echo '  version  "03.00"';
+               echo "  file     $1";
+             };;
+       *) usage;;
+    esac
+    shift
+done
+
+rm -f movstr?I*[xn].s movstr?I*[xn].asm
+
+#.Implementation_continued[=-----------------------------------------------
+#
+#      This generates the word aligned loop.  The loop is entered
+#      from the callable entry points ___movstrSI64nN, where at
+#      least N bytes will be copied.  r2 is the destination pointer
+#      offset by 4, r3 is the source pointer offset by 4, r6 is the
+#      loop count.  Thus, the total bytes moved is 64 * r6 + N.  The
+#      first value is is preloaded into r4 or r5 (r4 if N/4 is odd;
+#      r5 if N/4 is even).  Upon returning, r2 and r3 have been
+#      updated and may be used for the remainder bytes to move.
+#
+#      The code for this loop is generated by the awk program
+#      following.  Edit *it*, not what it generates!
+#
+#.End]=------------------------------------------------------------------*/
+
+gen_movstrN() {
+  awk $awk_flag "$awk_begin"'
+    if (abi) {
+      ps="#"; us=""; tf="a";
+    } else {
+      ps=""; us="_"; tf="x";
+    }
+  }
+  NR == 1 && NF == 4 {
+    mode = $1; suffix = $2; align = $3; count = $4;
+    ld = align; st = 0;
+
+    printf "; The following was calculated using awk.\n";
+    printf "\ttext\n";
+    printf "\talign\t16\n";
+    printf "loop%s%d:\n", mode, count * align;
+    printf "\taddu\t%sr3,%sr3,%d\n", ps, ps, count * align;
+    printf "\taddu\t%sr2,%sr2,%d\n", ps, ps, count * align;
+    printf "\tsubu\t%sr6,%sr6,1\n", ps, ps;
+    for (r = count + 1; r >= 1; r--) {
+      evenp = r % 2;
+      name = sprintf("__%smovstr%s%dn%d", us, mode, count * align, r * align);
+      if (r > 1) {
+        printf "\tglobal\t%s\n", name;
+        printf "%s:\n", name;
+      }
+      if (r > 2) {
+       printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
+        printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
+      } else if (r == 2) {
+       printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
+       printf "\tbcnd.n\t%sgt0,%sr6,loop%s%d\n", ps, ps, mode, count * align;
+        printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
+        printf "\tjmp.n\t%sr1\n", ps;
+      } else {
+        printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
+      }
+      ld += align; st += align;
+    }
+    if (!no_tdesc) {
+      printf "end%s%d:\n", mode, count * align;
+      printf "\tsection\t.tdesc,\"%s\"\n", tf;
+      printf "\tword\t0x42\n";
+      printf "\tword\t1\n";
+      printf "\tword\tloop%s%d\n", mode, count * align;
+      printf "\tword\tend%s%d\n", mode, count * align;
+      printf "\tword\t0x0100001f\n";
+      printf "\tword\t0\n";
+      printf "\tword\t1\n";
+      printf "\tword\t0\n";
+      printf "\ttext\n";
+    }
+    printf "; End of awk generated code.\n";
+    exit;
+  }'
+}
+
+(do_file '"movstrSI64n.s"';
+ echo 'SI::4:16' | gen_movstrN) > movstrSI64n.asm
+
+#.Implementation_continued[=-----------------------------------------------
+#
+#      This generates the even-remainder, straight-line modules.
+#      The code is entered from the callable entry points
+#      ___movstrXINxM, where exactly M bytes will be copied in XI
+#      mode.  r2 is the destination pointer, r3 is the source
+#      pointer, neither being offset.  The first value is preloaded
+#      into r4 or r5 (r4 if M-N/B is even; r5 if M-N/B is odd, where
+#      B is the mode size of XI).  Upon returning, r2 and r3 have not
+#      been changed.
+#
+#      The code for these cases is generated by the awk program
+#      following.  Edit *it*, not what it generates!
+#
+#.End]=------------------------------------------------------------------*/
+
+gen_movstrX0() {
+    awk $awk_flag "$awk_begin"'
+      if (abi) {
+       ps="#"; us=""; tf="a";
+      } else {
+       ps=""; us="_"; tf="x";
+      }
+    }
+    NR == 1 && NF == 4 {
+    mode = $1; suffix = $2; align = $3; bytes = $4;
+    ld = align; st = 0; count = bytes / align;
+    printf "; The following was calculated using awk.\n";
+    printf "\ttext\n";
+    printf "\talign\t16\n";
+    for (r = count; r >= 1; r--) {
+      evenp = r % 2;
+      name = sprintf("__%smovstr%s%dx%d", us, mode, count * align, r * align);
+      if (r > 1) {
+        printf "\tglobal\t%s\n", name;
+        printf "%s:\n", name;
+      }
+      if (r == 1)
+        printf "\tjmp.n\t%sr1\n", ps;
+      else
+        printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
+      printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
+      ld += align; st += align;
+    }
+    if (!no_tdesc) {
+      printf "end%s%dx:\n", mode, count * align;
+      printf "\tsection\t.tdesc,\"%s\"\n", tf;
+      printf "\tword\t0x42\n";
+      printf "\tword\t1\n";
+      printf "\tword\t__%smovstr%s%dx%d\n", us, mode, count * align, count * align;
+      printf "\tword\tend%s%dx\n", mode, count * align;
+      printf "\tword\t0x0100001f\n";
+      printf "\tword\t0\n";
+      printf "\tword\t1\n";
+      printf "\tword\t0\n";
+      printf "\ttext\n";
+    }
+    printf "; End of awk generated code.\n"
+    exit;
+  }'
+}
+
+(do_file '"movstrQI16x.s"';
+ echo 'QI:.b:1:16' | gen_movstrX0) > movstrQI16x.asm
+(do_file '"movstrHI48x.s"';
+ echo 'HI:.h:2:48' | gen_movstrX0) > movstrHI48x.asm
+(do_file '"movstrSI96x.s"';
+ echo 'SI::4:96'   | gen_movstrX0) > movstrSI96x.asm
+
+#.Implementation_continued[=-----------------------------------------------
+#
+#      This generates the odd-remainder, straight-line modules.  The
+#      interface is the same as that for the even-remainder modules.
+#
+#.End]=------------------------------------------------------------------*/
+
+gen_movstrXr() {
+    awk $awk_flag "$awk_begin"'
+      if (abi) {
+       ps="#"; us=""; tf="a";
+      } else {
+       ps=""; us="_"; tf="x";
+      }
+    }
+    NR == 1 && NF == 4 {
+    mode = $1; rem = $2; most = $3; count = $4;
+    suffix[1] = ".b"; suffix[2] = ".h"; suffix[4] = "";
+
+    prev = align = most;
+    ld = align; st = 0; total = count - rem - most;
+    evenp = int(total/align) % 2;
+    printf "; The following was calculated using awk.\n";
+    printf "\ttext\n";
+    printf "\talign\t16\n";
+    for (bytes = total; bytes >= 0; bytes -= align) {
+      if (bytes < align) {
+       if (bytes >= 2) align = 2;
+       else align = 1;
+      }
+      name = sprintf("__%smovstr%s%dx%d", us, mode, total + most, bytes + most);
+      if (bytes > most) {
+        printf "\tglobal\t%s\n", name;
+        printf "%s:\n", name;
+      }
+      if (bytes == 0)
+       printf "\tjmp.n\t%sr1\n", ps;
+      else
+       printf "\tld%s\t%sr%d,%sr3,%d\n", suffix[align], ps, 4 + evenp, ps, ld;
+      printf "\tst%s\t%sr%d,%sr2,%d\n", suffix[prev], ps, 5 - evenp, ps, st;
+      ld += align; st += prev; prev = align;
+      if (evenp)
+       evenp = 0;
+      else
+       evenp = 1;
+    }
+    if (!no_tdesc) {
+      printf "end%s%dx:\n", mode, total + most;
+      printf "\tsection\t.tdesc,\"%s\"\n", tf;
+      printf "\tword\t0x42\n";
+      printf "\tword\t1\n";
+      printf "\tword\t__%smovstr%s%dx%d\n", us, mode, total + most, total + most;
+      printf "\tword\tend%s%dx\n", mode, total + most;
+      printf "\tword\t0x0100001f\n";
+      printf "\tword\t0\n";
+      printf "\tword\t1\n";
+      printf "\tword\t0\n";
+      printf "\ttext\n";
+    }
+    printf "; End of awk generated code.\n"
+    exit;
+  }'
+}
+
+(do_file '"movstrSI47x.s"';
+ echo 'SI:1:4:48' | gen_movstrXr) > movstrSI47x.asm
+(do_file '"movstrSI46x.s"';
+ echo 'SI:2:4:48' | gen_movstrXr) > movstrSI46x.asm
+(do_file '"movstrSI45x.s"';
+ echo 'SI:3:4:48' | gen_movstrXr) > movstrSI45x.asm
+(do_file '"movstrHI15x.s"';
+ echo 'HI:1:2:16' | gen_movstrXr) > movstrHI15x.asm