From bbc83bc2cb0bcf15c047decf22b190247eb724bc Mon Sep 17 00:00:00 2001 From: Tom Wood Date: Fri, 3 Jan 1992 13:43:25 +0000 Subject: [PATCH] Initial revision From-SVN: r156 --- gcc/config/m88k/m88k-move.sh | 300 +++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100755 gcc/config/m88k/m88k-move.sh diff --git a/gcc/config/m88k/m88k-move.sh b/gcc/config/m88k/m88k-move.sh new file mode 100755 index 00000000000..ee139a214d2 --- /dev/null +++ b/gcc/config/m88k/m88k-move.sh @@ -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 -- 2.30.2