3 # If your shell doesn't support functions (true for some BSD users),
4 # you might try using GNU's bash.
6 #ident "@(#) m88k-move.sh 1-Sep-92"
8 # This file provided by Data General, February 1990.
10 # This script generates the necessary movstr library functions
11 # for the m88100. 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, moveSI64n
14 # implements a word aligned loop; the other modules, moveXINx
15 # implement a straight line copy of N bytes in mode XI.
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.
25 # The smaller, odd-remainder modules are provided to help
26 # mitigate the overhead of copying the last bytes.
28 # Changes to these functions should not be taken lightly if you
29 # want to be able to link programs built with older movstr
34 # 1-Sep-92 Stan Cox Added moveDI96x, moveDI41x through moveDI47x.
35 # 2-Jan-92 Tom Wood Renamed files to comply with SVR3 14 char limit.
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
53 # 22-Feb-90 Tom Wood Created.
54 # 20-Jun-90 Tom Wood Emit file directives.
56 #.End]=--------------------------------------------------------------*/
59 echo "usage: $0 [ -abi ] [ -no-tdesc ]" 1>&2
65 ps
=""; us
="_"; tf
="x"; la
="@L"; fb
="8"; nt
="";
70 while [ $# -gt 0 ] ; do
72 -no-tdesc) awk_begin
="$awk_begin no_tdesc=1;"
74 -abi) awk_begin
="$awk_begin abi=1;"
75 ps
="#"; us
=""; tf
="a"; la
=".L"; fb
="16";
77 echo ' version "03.00"';
85 rm -f move?I
*[xn
].s move?I
*[xn
].asm
87 #.Implementation_continued[=-----------------------------------------------
89 # This generates the word aligned loop. The loop is entered
90 # from the callable entry points ___movstrSI64nN, where at
91 # least N bytes will be copied. r2 is the destination pointer
92 # offset by 4, r3 is the source pointer offset by 4, r6 is the
93 # loop count. Thus, the total bytes moved is 64 * r6 + N. The
94 # first value is is preloaded into r4 or r5 (r4 if N/4 is odd;
95 # r5 if N/4 is even). Upon returning, r2 and r3 have been
96 # updated and may be used for the remainder bytes to move.
98 # The code for this loop is generated by the awk program
99 # following. Edit *it*, not what it generates!
101 #.End]=------------------------------------------------------------------*/
104 awk $awk_flag "$awk_begin"'
106 ps="#"; us=""; tf="a"; la=".L"; fb=16;
108 ps=""; us="_"; tf="x"; la="@L"; fb=8;
112 mode = $1; suffix = $2; align = $3; count = $4;
115 printf "; The following was calculated using awk.\n";
117 printf "\talign\t%d\n", fb;
118 printf "%sloop%s%d:\n", la, mode, count * align;
119 printf "\taddu\t%sr3,%sr3,%d\n", ps, ps, count * align;
120 printf "\taddu\t%sr2,%sr2,%d\n", ps, ps, count * align;
121 printf "\tsubu\t%sr6,%sr6,1\n", ps, ps;
122 for (r = count + 1; r >= 1; r--) {
124 name = sprintf("__%smovstr%s%dn%d", us, mode, count * align, r * align);
126 printf "\tglobal\t%s\n", name;
127 printf "%s:\n", name;
130 printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
131 printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
133 printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
134 printf "\tbcnd.n\t%sgt0,%sr6,%sloop%s%d\n", ps, ps, la, mode, count * align;
135 printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
136 printf "\tjmp.n\t%sr1\n", ps;
138 printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
140 ld += align; st += align;
143 printf "%send%s%d:\n", la, mode, count * align;
144 printf "\tsection\t.tdesc,\"%s\"\n", tf;
145 printf "\tword\t0x42,1,%sloop%s%d", la, mode, count * align;
146 printf ",%send%s%d\n", la, mode, count * align;
147 printf "\tword\t0x0100001f,0,1,0\n";
150 printf "; End of awk generated code.\n";
155 (do_file
'"movstrSI64n.s"';
156 echo 'SI::4:16' | gen_movstrN
) > moveSI64n.asm
158 #.Implementation_continued[=-----------------------------------------------
160 # This generates the even-remainder, straight-line modules.
161 # The code is entered from the callable entry points
162 # ___movstrXINxM, where exactly M bytes will be copied in XI
163 # mode. r2 is the destination pointer, r3 is the source
164 # pointer, neither being offset. The first value is preloaded
165 # into r4 or r5 (r4 if M-N/B is even; r5 if M-N/B is odd, where
166 # B is the mode size of XI). Upon returning, r2 and r3 have not
169 # The code for these cases is generated by the awk program
170 # following. Edit *it*, not what it generates!
172 #.End]=------------------------------------------------------------------*/
175 awk $awk_flag "$awk_begin"'
177 ps="#"; us=""; tf="a"; la=".L"; fb=16;
179 ps=""; us="_"; tf="x"; la="@L"; fb=8;
183 mode = $1; suffix = $2; align = $3; bytes = $4;
184 ld = align; st = 0; count = bytes / align;
185 reg[0] = 4; if (align == 8) reg[1] = 6; else reg[1] = 5;
186 printf "; The following was calculated using awk.\n";
188 printf "\talign\t%d\n", fb;
189 for (r = count; r >= 1; r--) {
191 name = sprintf("__%smovstr%s%dx%d", us, mode, count * align, r * align);
193 printf "\tglobal\t%s\n", name;
194 printf "%s:\n", name;
197 printf "\tjmp.n\t%sr1\n", ps;
199 printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, reg[evenp], ps, ld;
200 printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, reg[1-evenp], ps, st;
201 ld += align; st += align;
204 printf "%send%s%dx:\n", la, mode, count * align;
205 printf "\tsection\t.tdesc,\"%s\"\n", tf;
206 printf "\tword\t0x42,1,__%smovstr%s%dx%d", us, mode, count * align, count * align;
207 printf ",%send%s%dx\n", la, mode, count * align;
208 printf "\tword\t0x0100001f,0,1,0\n";
211 printf "; End of awk generated code.\n"
216 (do_file
'"movstrQI16x.s"';
217 echo 'QI:.b:1:16' | gen_movstrX0
) > moveQI16x.asm
218 (do_file
'"movstrHI48x.s"';
219 echo 'HI:.h:2:48' | gen_movstrX0
) > moveHI48x.asm
220 (do_file
'"movstrSI96x.s"';
221 echo 'SI::4:96' | gen_movstrX0
) > moveSI96x.asm
222 (do_file
'"movstrDI96x.s"';
223 echo 'DI:.d:8:96' | gen_movstrX0
) > moveDI96x.asm
225 #.Implementation_continued[=-----------------------------------------------
227 # This generates the odd-remainder, straight-line modules. The
228 # interface is the same as that for the even-remainder modules.
230 #.End]=------------------------------------------------------------------*/
233 awk $awk_flag "$awk_begin"'
235 ps="#"; us=""; tf="a"; la=".L"; fb=16;
237 ps=""; us="_"; tf="x"; la="@L"; fb=8;
241 mode = $1; rem = $2; most = $3; count = $4;
242 suffix[1] = ".b"; suffix[2] = ".h"; suffix[4] = ""; suffix[8] = ".d";
245 ld = align; st = 0; total = count - rem - most;
246 evenp = int(total/align) % 2;
247 reg[0] = 4; if (align == 8) reg[1] = 6; else reg[1] = 5;
248 printf "; The following was calculated using awk.\n";
250 printf "\talign\t%d\n", fb;
251 for (bytes = total; bytes >= 0; bytes -= align) {
253 if (bytes >= 4) align = 4;
254 else if (bytes >= 2) align = 2;
257 name = sprintf("__%smovstr%s%dx%d", us, mode, total + most, bytes + most);
259 printf "\tglobal\t%s\n", name;
260 printf "%s:\n", name;
263 printf "\tjmp.n\t%sr1\n", ps;
265 printf "\tld%s\t%sr%d,%sr3,%d\n", suffix[align], ps, reg[evenp], ps, ld;
266 printf "\tst%s\t%sr%d,%sr2,%d\n", suffix[prev], ps, reg[1-evenp], ps, st;
267 ld += align; st += prev; prev = align;
271 printf "%send%s%dx:\n", la, mode, total + most;
272 printf "\tsection\t.tdesc,\"%s\"\n", tf;
273 printf "\tword\t0x42,1,__%smovstr%s%dx%d", us, mode, total + most, total + most;
274 printf ",%send%s%dx\n", la, mode, total + most;
275 printf "\tword\t0x0100001f,0,1,0\n";
278 printf "; End of awk generated code.\n"
283 (do_file
'"movstrDI47x.s"';
284 echo 'DI:1:8:48' | gen_movstrXr
) > moveDI47x.asm
285 (do_file
'"movstrDI46x.s"';
286 echo 'DI:2:8:48' | gen_movstrXr
) > moveDI46x.asm
287 (do_file
'"movstrDI45x.s"';
288 echo 'DI:3:8:48' | gen_movstrXr
) > moveDI45x.asm
289 (do_file
'"movstrDI44x.s"';
290 echo 'DI:4:8:48' | gen_movstrXr
) > moveDI44x.asm
291 (do_file
'"movstrDI43x.s"';
292 echo 'DI:5:8:48' | gen_movstrXr
) > moveDI43x.asm
293 (do_file
'"movstrDI42x.s"';
294 echo 'DI:6:8:48' | gen_movstrXr
) > moveDI42x.asm
295 (do_file
'"movstrDI41x.s"';
296 echo 'DI:7:8:48' | gen_movstrXr
) > moveDI41x.asm
298 (do_file
'"movstrSI47x.s"';
299 echo 'SI:1:4:48' | gen_movstrXr
) > moveSI47x.asm
300 (do_file
'"movstrSI46x.s"';
301 echo 'SI:2:4:48' | gen_movstrXr
) > moveSI46x.asm
302 (do_file
'"movstrSI45x.s"';
303 echo 'SI:3:4:48' | gen_movstrXr
) > moveSI45x.asm
305 (do_file
'"movstrHI15x.s"';
306 echo 'HI:1:2:16' | gen_movstrXr
) > moveHI15x.asm