Initial revision
From-SVN: r156
This commit is contained in:
parent
ec04a5a3c9
commit
bbc83bc2cb
300
gcc/config/m88k/m88k-move.sh
Executable file
300
gcc/config/m88k/m88k-move.sh
Executable file
@ -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
|
Loading…
Reference in New Issue
Block a user