OSDN Git Service

Initial revision
[pf3gnuchains/gcc-fork.git] / gcc / config / m88k / m88k-move.sh
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 "@(#) m88k-move.sh 1-Sep-92"
7 #
8 #       This file provided by Data General, February 1990.
9 #
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.
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.
31 #
32 #.Revision History
33 #
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
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 ps=""; us="_"; tf="x"; la="@L"; fb="8"; nt="";
66 do_file() {
67     echo "      file     $1";
68 }
69
70 while [ $# -gt 0 ] ; do
71     case $1 in
72         -no-tdesc) awk_begin="$awk_begin no_tdesc=1;"
73               nt=";";;
74         -abi) awk_begin="$awk_begin abi=1;"
75               ps="#"; us=""; tf="a"; la=".L"; fb="16";
76               do_file() {
77                 echo '  version  "03.00"';
78                 echo "  file     $1";
79               };;
80         *) usage;;
81     esac
82     shift
83 done
84
85 rm -f move?I*[xn].s move?I*[xn].asm
86
87 #.Implementation_continued[=-----------------------------------------------
88 #
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.
97 #
98 #       The code for this loop is generated by the awk program
99 #       following.  Edit *it*, not what it generates!
100 #
101 #.End]=------------------------------------------------------------------*/
102
103 gen_movstrN() {
104   awk $awk_flag "$awk_begin"'
105     if (abi) {
106       ps="#"; us=""; tf="a"; la=".L"; fb=16;
107     } else {
108       ps=""; us="_"; tf="x"; la="@L"; fb=8;
109     }
110   }
111   NR == 1 && NF == 4 {
112     mode = $1; suffix = $2; align = $3; count = $4;
113     ld = align; st = 0;
114
115     printf "; The following was calculated using awk.\n";
116     printf "\ttext\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--) {
123       evenp = r % 2;
124       name = sprintf("__%smovstr%s%dn%d", us, mode, count * align, r * align);
125       if (r > 1) {
126         printf "\tglobal\t%s\n", name;
127         printf "%s:\n", name;
128       }
129       if (r > 2) {
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;
132       } else if (r == 2) {
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;
137       } else {
138         printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
139       }
140       ld += align; st += align;
141     }
142     if (!no_tdesc) {
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";
148       printf "\ttext\n";
149     }
150     printf "; End of awk generated code.\n";
151     exit;
152   }'
153 }
154
155 (do_file '"movstrSI64n.s"';
156  echo 'SI::4:16' | gen_movstrN) > moveSI64n.asm
157
158 #.Implementation_continued[=-----------------------------------------------
159 #
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
167 #       been changed.
168 #
169 #       The code for these cases is generated by the awk program
170 #       following.  Edit *it*, not what it generates!
171 #
172 #.End]=------------------------------------------------------------------*/
173
174 gen_movstrX0() {
175     awk $awk_flag "$awk_begin"'
176       if (abi) {
177         ps="#"; us=""; tf="a"; la=".L"; fb=16;
178       } else {
179         ps=""; us="_"; tf="x"; la="@L"; fb=8;
180       }
181     }
182     NR == 1 && NF == 4 {
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";
187     printf "\ttext\n";
188     printf "\talign\t%d\n", fb;
189     for (r = count; r >= 1; r--) {
190       evenp = r % 2;
191       name = sprintf("__%smovstr%s%dx%d", us, mode, count * align, r * align);
192       if (r > 1) {
193         printf "\tglobal\t%s\n", name;
194         printf "%s:\n", name;
195       }
196       if (r == 1)
197         printf "\tjmp.n\t%sr1\n", ps;
198       else
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;
202     }
203     if (!no_tdesc) {
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";
209       printf "\ttext\n";
210     }
211     printf "; End of awk generated code.\n"
212     exit;
213   }'
214 }
215
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
224
225 #.Implementation_continued[=-----------------------------------------------
226 #
227 #       This generates the odd-remainder, straight-line modules.  The
228 #       interface is the same as that for the even-remainder modules.
229 #
230 #.End]=------------------------------------------------------------------*/
231
232 gen_movstrXr() {
233     awk $awk_flag "$awk_begin"'
234       if (abi) {
235         ps="#"; us=""; tf="a"; la=".L"; fb=16;
236       } else {
237         ps=""; us="_"; tf="x"; la="@L"; fb=8;
238       }
239     }
240     NR == 1 && NF == 4 {
241     mode = $1; rem = $2; most = $3; count = $4;
242     suffix[1] = ".b"; suffix[2] = ".h"; suffix[4] = ""; suffix[8] = ".d";
243
244     prev = align = most;
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";
249     printf "\ttext\n";
250     printf "\talign\t%d\n", fb;
251     for (bytes = total; bytes >= 0; bytes -= align) {
252       if (bytes < align) {
253         if (bytes >= 4) align = 4;
254         else if (bytes >= 2) align = 2;
255         else align = 1;
256       }
257       name = sprintf("__%smovstr%s%dx%d", us, mode, total + most, bytes + most);
258       if (bytes > most) {
259         printf "\tglobal\t%s\n", name;
260         printf "%s:\n", name;
261       }
262       if (bytes == 0)
263         printf "\tjmp.n\t%sr1\n", ps;
264       else
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;
268       evenp = 1 - evenp;
269     }
270     if (!no_tdesc) {
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";
276       printf "\ttext\n";
277     }
278     printf "; End of awk generated code.\n"
279     exit;
280   }'
281 }
282
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
297
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
304
305 (do_file '"movstrHI15x.s"';
306  echo 'HI:1:2:16' | gen_movstrXr) > moveHI15x.asm