home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / config / m88k-movstr.sh < prev    next >
Linux/UNIX/POSIX Shell Script  |  1991-06-03  |  10KB  |  301 lines

  1. #!/bin/sh
  2. #
  3. #    If your shell doesn't support functions (true for some BSD users),
  4. #    you might try using GNU's bash.
  5. #
  6. #ident "@(#) movstr-m88k.sh 17-Oct-90"
  7. #
  8. #    This file provided by Data General, Feburary 1990.
  9. #
  10. #    This script generates the necessary movstr library functions
  11. #    for the m88000.  These functions are called from the expansion
  12. #    of movstrsi.  There are eight modules created by this script,
  13. #    each with multiple entry points.  One module, movstrSI64n
  14. #    implements a word aligned loop; the other modules, movstrXINx
  15. #    implement a straight line copy of N bytes in mode XI.
  16. #
  17. #    By analysis of the best memcpy function, it can be determined
  18. #    what appear to be certain magic numbers.  For example, a
  19. #    memcpy of 13 bytes, where the pointers are determined at run
  20. #    time to be word aligned takes 28 cycles.  A call to
  21. #    __movstrQI13x13 also takes 28 cycles.  The break even point
  22. #    for a HImode copy is 38 bytes.  Just to be on the safe side,
  23. #    these are bumped to 16 and 48 respectively.
  24. #
  25. #    The smaller, odd-remainder modules are provided to help
  26. #    mitigate the overhead of copying the last bytes.
  27. #
  28. #    Changes to these functions should not be taken lightly if you
  29. #    want to be able to link programs built with older movstr
  30. #    parameters.  For this reason, Makefile regards movstr*.s as
  31. #    source modules and does not have a rule for creating them
  32. #    automatically.
  33. #
  34. #.Revision History
  35. #
  36. #    26-Oct-90   Tom Wood   Delete movstr.h; moved to out-m88k.c.
  37. #    17-Oct-90   Tom Wood   Files are named *.asm rather than *.s.
  38. #    11-Sep-90   Jeffrey Friedl
  39. #            On my BSD 4.3 awk and my GNU-awk, only the
  40. #            first character of an argument to -F is passed
  41. #            through, so I can't get this to work.
  42. #     5-Sep-90   Ray Essick/Tom Wood  
  43. #            Added a -no-tdesc option.
  44. #    27-Aug-90   Vince Guarna/Tom Wood   
  45. #            Version 3 assembler syntax (-abi).
  46. #    16-Aug-90   Ron Guilmette
  47. #            Avoid problems on a Sparc.  The common
  48. #            denominator among shells seems to be '...\'
  49. #            rather than '...\\'.
  50. #    15-Aug-90   Ron Guilmette
  51. #            Avoid awk syntax errors on a Sun by not using
  52. #            the `!' operator.
  53. #    22-Feb-90   Tom Wood      Created.
  54. #    20-Jun-90   Tom Wood    Emit file directives.
  55. #
  56. #.End]=--------------------------------------------------------------*/
  57.  
  58. usage() {
  59.     echo "usage: $0 [ -abi ] [ -no-tdesc ]" 1>&2
  60.     exit 1
  61. }
  62.  
  63. awk_flag="-F:";
  64. awk_begin="BEGIN { "
  65. do_file() {
  66.     echo "    file     $1";
  67. }
  68.  
  69. while [ $# -gt 0 ] ; do
  70.     case $1 in
  71.     -no-tdesc) awk_begin="$awk_begin no_tdesc=1;";;
  72.     -abi) awk_begin="$awk_begin abi=1;"
  73.           do_file() {
  74.         echo '    version     "03.00"';
  75.         echo "    file     $1";
  76.           };;
  77.     *) usage;;
  78.     esac
  79.     shift
  80. done
  81.  
  82. rm -f movstr?I*[xn].s movstr?I*[xn].asm
  83.  
  84. #.Implementation_continued[=-----------------------------------------------
  85. #
  86. #    This generates the word aligned loop.  The loop is entered
  87. #    from the callable entry points ___movstrSI64nN, where at
  88. #    least N bytes will be copied.  r2 is the destination pointer
  89. #    offset by 4, r3 is the source pointer offset by 4, r6 is the
  90. #    loop count.  Thus, the total bytes moved is 64 * r6 + N.  The
  91. #    first value is is preloaded into r4 or r5 (r4 if N/4 is odd;
  92. #    r5 if N/4 is even).  Upon returning, r2 and r3 have been
  93. #    updated and may be used for the remainder bytes to move.
  94. #
  95. #    The code for this loop is generated by the awk program
  96. #    following.  Edit *it*, not what it generates!
  97. #
  98. #.End]=------------------------------------------------------------------*/
  99.  
  100. gen_movstrN() {
  101.   awk $awk_flag "$awk_begin"'
  102.     if (abi) {
  103.       ps="#"; us=""; tf="a";
  104.     } else {
  105.       ps=""; us="_"; tf="x";
  106.     }
  107.   }
  108.   NR == 1 && NF == 4 {
  109.     mode = $1; suffix = $2; align = $3; count = $4;
  110.     ld = align; st = 0;
  111.  
  112.     printf "; The following was calculated using awk.\n";
  113.     printf "\ttext\n";
  114.     printf "\talign\t16\n";
  115.     printf "loop%s%d:\n", mode, count * align;
  116.     printf "\taddu\t%sr3,%sr3,%d\n", ps, ps, count * align;
  117.     printf "\taddu\t%sr2,%sr2,%d\n", ps, ps, count * align;
  118.     printf "\tsubu\t%sr6,%sr6,1\n", ps, ps;
  119.     for (r = count + 1; r >= 1; r--) {
  120.       evenp = r % 2;
  121.       name = sprintf("__%smovstr%s%dn%d", us, mode, count * align, r * align);
  122.       if (r > 1) {
  123.         printf "\tglobal\t%s\n", name;
  124.         printf "%s:\n", name;
  125.       }
  126.       if (r > 2) {
  127.     printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
  128.         printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
  129.       } else if (r == 2) {
  130.     printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
  131.     printf "\tbcnd.n\t%sgt0,%sr6,loop%s%d\n", ps, ps, mode, count * align;
  132.         printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
  133.         printf "\tjmp.n\t%sr1\n", ps;
  134.       } else {
  135.         printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
  136.       }
  137.       ld += align; st += align;
  138.     }
  139.     if (!no_tdesc) {
  140.       printf "end%s%d:\n", mode, count * align;
  141.       printf "\tsection\t.tdesc,\"%s\"\n", tf;
  142.       printf "\tword\t0x42\n";
  143.       printf "\tword\t1\n";
  144.       printf "\tword\tloop%s%d\n", mode, count * align;
  145.       printf "\tword\tend%s%d\n", mode, count * align;
  146.       printf "\tword\t0x0100001f\n";
  147.       printf "\tword\t0\n";
  148.       printf "\tword\t1\n";
  149.       printf "\tword\t0\n";
  150.       printf "\ttext\n";
  151.     }
  152.     printf "; End of awk generated code.\n";
  153.     exit;
  154.   }'
  155. }
  156.  
  157. (do_file '"movstrSI64n.s"';
  158.  echo 'SI::4:16' | gen_movstrN) > movstrSI64n.asm
  159.  
  160. #.Implementation_continued[=-----------------------------------------------
  161. #
  162. #    This generates the even-remainder, straight-line modules.
  163. #    The code is entered from the callable entry points
  164. #    ___movstrXINxM, where exactly M bytes will be copied in XI
  165. #    mode.  r2 is the destination pointer, r3 is the source
  166. #    pointer, neither being offset.  The first value is preloaded
  167. #    into r4 or r5 (r4 if M-N/B is even; r5 if M-N/B is odd, where
  168. #    B is the mode size of XI).  Upon returning, r2 and r3 have not
  169. #    been changed.
  170. #
  171. #    The code for these cases is generated by the awk program
  172. #    following.  Edit *it*, not what it generates!
  173. #
  174. #.End]=------------------------------------------------------------------*/
  175.  
  176. gen_movstrX0() {
  177.     awk $awk_flag "$awk_begin"'
  178.       if (abi) {
  179.     ps="#"; us=""; tf="a";
  180.       } else {
  181.     ps=""; us="_"; tf="x";
  182.       }
  183.     }
  184.     NR == 1 && NF == 4 {
  185.     mode = $1; suffix = $2; align = $3; bytes = $4;
  186.     ld = align; st = 0; count = bytes / align;
  187.     printf "; The following was calculated using awk.\n";
  188.     printf "\ttext\n";
  189.     printf "\talign\t16\n";
  190.     for (r = count; r >= 1; r--) {
  191.       evenp = r % 2;
  192.       name = sprintf("__%smovstr%s%dx%d", us, mode, count * align, r * align);
  193.       if (r > 1) {
  194.         printf "\tglobal\t%s\n", name;
  195.         printf "%s:\n", name;
  196.       }
  197.       if (r == 1)
  198.         printf "\tjmp.n\t%sr1\n", ps;
  199.       else
  200.         printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
  201.       printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
  202.       ld += align; st += align;
  203.     }
  204.     if (!no_tdesc) {
  205.       printf "end%s%dx:\n", mode, count * align;
  206.       printf "\tsection\t.tdesc,\"%s\"\n", tf;
  207.       printf "\tword\t0x42\n";
  208.       printf "\tword\t1\n";
  209.       printf "\tword\t__%smovstr%s%dx%d\n", us, mode, count * align, count * align;
  210.       printf "\tword\tend%s%dx\n", mode, count * align;
  211.       printf "\tword\t0x0100001f\n";
  212.       printf "\tword\t0\n";
  213.       printf "\tword\t1\n";
  214.       printf "\tword\t0\n";
  215.       printf "\ttext\n";
  216.     }
  217.     printf "; End of awk generated code.\n"
  218.     exit;
  219.   }'
  220. }
  221.  
  222. (do_file '"movstrQI16x.s"';
  223.  echo 'QI:.b:1:16' | gen_movstrX0) > movstrQI16x.asm
  224. (do_file '"movstrHI48x.s"';
  225.  echo 'HI:.h:2:48' | gen_movstrX0) > movstrHI48x.asm
  226. (do_file '"movstrSI96x.s"';
  227.  echo 'SI::4:96'   | gen_movstrX0) > movstrSI96x.asm
  228.  
  229. #.Implementation_continued[=-----------------------------------------------
  230. #
  231. #    This generates the odd-remainder, straight-line modules.  The
  232. #    interface is the same as that for the even-remainder modules.
  233. #
  234. #.End]=------------------------------------------------------------------*/
  235.  
  236. gen_movstrXr() {
  237.     awk $awk_flag "$awk_begin"'
  238.       if (abi) {
  239.     ps="#"; us=""; tf="a";
  240.       } else {
  241.     ps=""; us="_"; tf="x";
  242.       }
  243.     }
  244.     NR == 1 && NF == 4 {
  245.     mode = $1; rem = $2; most = $3; count = $4;
  246.     suffix[1] = ".b"; suffix[2] = ".h"; suffix[4] = "";
  247.  
  248.     prev = align = most;
  249.     ld = align; st = 0; total = count - rem - most;
  250.     evenp = int(total/align) % 2;
  251.     printf "; The following was calculated using awk.\n";
  252.     printf "\ttext\n";
  253.     printf "\talign\t16\n";
  254.     for (bytes = total; bytes >= 0; bytes -= align) {
  255.       if (bytes < align) {
  256.     if (bytes >= 2) align = 2;
  257.     else align = 1;
  258.       }
  259.       name = sprintf("__%smovstr%s%dx%d", us, mode, total + most, bytes + most);
  260.       if (bytes > most) {
  261.         printf "\tglobal\t%s\n", name;
  262.         printf "%s:\n", name;
  263.       }
  264.       if (bytes == 0)
  265.     printf "\tjmp.n\t%sr1\n", ps;
  266.       else
  267.     printf "\tld%s\t%sr%d,%sr3,%d\n", suffix[align], ps, 4 + evenp, ps, ld;
  268.       printf "\tst%s\t%sr%d,%sr2,%d\n", suffix[prev], ps, 5 - evenp, ps, st;
  269.       ld += align; st += prev; prev = align;
  270.       if (evenp)
  271.     evenp = 0;
  272.       else
  273.     evenp = 1;
  274.     }
  275.     if (!no_tdesc) {
  276.       printf "end%s%dx:\n", mode, total + most;
  277.       printf "\tsection\t.tdesc,\"%s\"\n", tf;
  278.       printf "\tword\t0x42\n";
  279.       printf "\tword\t1\n";
  280.       printf "\tword\t__%smovstr%s%dx%d\n", us, mode, total + most, total + most;
  281.       printf "\tword\tend%s%dx\n", mode, total + most;
  282.       printf "\tword\t0x0100001f\n";
  283.       printf "\tword\t0\n";
  284.       printf "\tword\t1\n";
  285.       printf "\tword\t0\n";
  286.       printf "\ttext\n";
  287.     }
  288.     printf "; End of awk generated code.\n"
  289.     exit;
  290.   }'
  291. }
  292.  
  293. (do_file '"movstrSI47x.s"';
  294.  echo 'SI:1:4:48' | gen_movstrXr) > movstrSI47x.asm
  295. (do_file '"movstrSI46x.s"';
  296.  echo 'SI:2:4:48' | gen_movstrXr) > movstrSI46x.asm
  297. (do_file '"movstrSI45x.s"';
  298.  echo 'SI:3:4:48' | gen_movstrXr) > movstrSI45x.asm
  299. (do_file '"movstrHI15x.s"';
  300.  echo 'HI:1:2:16' | gen_movstrXr) > movstrHI15x.asm
  301.