|
|
1.1 root 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 3-Jan-92"
7: #
1.1.1.2 ! root 8: # This file provided by Data General, February 1990.
1.1 root 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: # 2-Jan-92 Tom Wood Renamed files to comply with SVR3 14 char limit.
35: # 26-Oct-90 Tom Wood Delete movstr.h; moved to out-m88k.c.
36: # 17-Oct-90 Tom Wood Files are named *.asm rather than *.s.
37: # 11-Sep-90 Jeffrey Friedl
38: # On my BSD 4.3 awk and my GNU-awk, only the
39: # first character of an argument to -F is passed
40: # through, so I can't get this to work.
41: # 5-Sep-90 Ray Essick/Tom Wood
42: # Added a -no-tdesc option.
43: # 27-Aug-90 Vince Guarna/Tom Wood
44: # Version 3 assembler syntax (-abi).
45: # 16-Aug-90 Ron Guilmette
46: # Avoid problems on a Sparc. The common
47: # denominator among shells seems to be '...\'
48: # rather than '...\\'.
49: # 15-Aug-90 Ron Guilmette
50: # Avoid awk syntax errors on a Sun by not using
51: # the `!' operator.
52: # 22-Feb-90 Tom Wood Created.
53: # 20-Jun-90 Tom Wood Emit file directives.
54: #
55: #.End]=--------------------------------------------------------------*/
56:
57: usage() {
58: echo "usage: $0 [ -abi ] [ -no-tdesc ]" 1>&2
59: exit 1
60: }
61:
62: awk_flag="-F:";
63: awk_begin="BEGIN { "
64: do_file() {
65: echo " file $1";
66: }
67:
68: while [ $# -gt 0 ] ; do
69: case $1 in
70: -no-tdesc) awk_begin="$awk_begin no_tdesc=1;";;
71: -abi) awk_begin="$awk_begin abi=1;"
72: do_file() {
73: echo ' version "03.00"';
74: echo " file $1";
75: };;
76: *) usage;;
77: esac
78: shift
79: done
80:
81: rm -f move?I*[xn].s move?I*[xn].asm
82:
83: #.Implementation_continued[=-----------------------------------------------
84: #
85: # This generates the word aligned loop. The loop is entered
86: # from the callable entry points ___movstrSI64nN, where at
87: # least N bytes will be copied. r2 is the destination pointer
88: # offset by 4, r3 is the source pointer offset by 4, r6 is the
89: # loop count. Thus, the total bytes moved is 64 * r6 + N. The
90: # first value is is preloaded into r4 or r5 (r4 if N/4 is odd;
91: # r5 if N/4 is even). Upon returning, r2 and r3 have been
92: # updated and may be used for the remainder bytes to move.
93: #
94: # The code for this loop is generated by the awk program
95: # following. Edit *it*, not what it generates!
96: #
97: #.End]=------------------------------------------------------------------*/
98:
99: gen_movstrN() {
100: awk $awk_flag "$awk_begin"'
101: if (abi) {
102: ps="#"; us=""; tf="a";
103: } else {
104: ps=""; us="_"; tf="x";
105: }
106: }
107: NR == 1 && NF == 4 {
108: mode = $1; suffix = $2; align = $3; count = $4;
109: ld = align; st = 0;
110:
111: printf "; The following was calculated using awk.\n";
112: printf "\ttext\n";
113: printf "\talign\t16\n";
114: printf "loop%s%d:\n", mode, count * align;
115: printf "\taddu\t%sr3,%sr3,%d\n", ps, ps, count * align;
116: printf "\taddu\t%sr2,%sr2,%d\n", ps, ps, count * align;
117: printf "\tsubu\t%sr6,%sr6,1\n", ps, ps;
118: for (r = count + 1; r >= 1; r--) {
119: evenp = r % 2;
120: name = sprintf("__%smovstr%s%dn%d", us, mode, count * align, r * align);
121: if (r > 1) {
122: printf "\tglobal\t%s\n", name;
123: printf "%s:\n", name;
124: }
125: if (r > 2) {
126: printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
127: printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
128: } else if (r == 2) {
129: printf "\tld%s\t%sr%d,%sr3,%d\n", suffix, ps, 4 + evenp, ps, ld;
130: printf "\tbcnd.n\t%sgt0,%sr6,loop%s%d\n", ps, ps, mode, count * align;
131: printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
132: printf "\tjmp.n\t%sr1\n", ps;
133: } else {
134: printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
135: }
136: ld += align; st += align;
137: }
138: if (!no_tdesc) {
139: printf "end%s%d:\n", mode, count * align;
140: printf "\tsection\t.tdesc,\"%s\"\n", tf;
141: printf "\tword\t0x42\n";
142: printf "\tword\t1\n";
143: printf "\tword\tloop%s%d\n", mode, count * align;
144: printf "\tword\tend%s%d\n", mode, count * align;
145: printf "\tword\t0x0100001f\n";
146: printf "\tword\t0\n";
147: printf "\tword\t1\n";
148: printf "\tword\t0\n";
149: printf "\ttext\n";
150: }
151: printf "; End of awk generated code.\n";
152: exit;
153: }'
154: }
155:
156: (do_file '"movstrSI64n.s"';
157: echo 'SI::4:16' | gen_movstrN) > moveSI64n.asm
158:
159: #.Implementation_continued[=-----------------------------------------------
160: #
161: # This generates the even-remainder, straight-line modules.
162: # The code is entered from the callable entry points
163: # ___movstrXINxM, where exactly M bytes will be copied in XI
164: # mode. r2 is the destination pointer, r3 is the source
165: # pointer, neither being offset. The first value is preloaded
166: # into r4 or r5 (r4 if M-N/B is even; r5 if M-N/B is odd, where
167: # B is the mode size of XI). Upon returning, r2 and r3 have not
168: # been changed.
169: #
170: # The code for these cases is generated by the awk program
171: # following. Edit *it*, not what it generates!
172: #
173: #.End]=------------------------------------------------------------------*/
174:
175: gen_movstrX0() {
176: awk $awk_flag "$awk_begin"'
177: if (abi) {
178: ps="#"; us=""; tf="a";
179: } else {
180: ps=""; us="_"; tf="x";
181: }
182: }
183: NR == 1 && NF == 4 {
184: mode = $1; suffix = $2; align = $3; bytes = $4;
185: ld = align; st = 0; count = bytes / align;
186: printf "; The following was calculated using awk.\n";
187: printf "\ttext\n";
188: printf "\talign\t16\n";
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, 4 + evenp, ps, ld;
200: printf "\tst%s\t%sr%d,%sr2,%d\n", suffix, ps, 5 - evenp, ps, st;
201: ld += align; st += align;
202: }
203: if (!no_tdesc) {
204: printf "end%s%dx:\n", mode, count * align;
205: printf "\tsection\t.tdesc,\"%s\"\n", tf;
206: printf "\tword\t0x42\n";
207: printf "\tword\t1\n";
208: printf "\tword\t__%smovstr%s%dx%d\n", us, mode, count * align, count * align;
209: printf "\tword\tend%s%dx\n", mode, count * align;
210: printf "\tword\t0x0100001f\n";
211: printf "\tword\t0\n";
212: printf "\tword\t1\n";
213: printf "\tword\t0\n";
214: printf "\ttext\n";
215: }
216: printf "; End of awk generated code.\n"
217: exit;
218: }'
219: }
220:
221: (do_file '"movstrQI16x.s"';
222: echo 'QI:.b:1:16' | gen_movstrX0) > moveQI16x.asm
223: (do_file '"movstrHI48x.s"';
224: echo 'HI:.h:2:48' | gen_movstrX0) > moveHI48x.asm
225: (do_file '"movstrSI96x.s"';
226: echo 'SI::4:96' | gen_movstrX0) > moveSI96x.asm
227:
228: #.Implementation_continued[=-----------------------------------------------
229: #
230: # This generates the odd-remainder, straight-line modules. The
231: # interface is the same as that for the even-remainder modules.
232: #
233: #.End]=------------------------------------------------------------------*/
234:
235: gen_movstrXr() {
236: awk $awk_flag "$awk_begin"'
237: if (abi) {
238: ps="#"; us=""; tf="a";
239: } else {
240: ps=""; us="_"; tf="x";
241: }
242: }
243: NR == 1 && NF == 4 {
244: mode = $1; rem = $2; most = $3; count = $4;
245: suffix[1] = ".b"; suffix[2] = ".h"; suffix[4] = "";
246:
247: prev = align = most;
248: ld = align; st = 0; total = count - rem - most;
249: evenp = int(total/align) % 2;
250: printf "; The following was calculated using awk.\n";
251: printf "\ttext\n";
252: printf "\talign\t16\n";
253: for (bytes = total; bytes >= 0; bytes -= align) {
254: if (bytes < align) {
255: if (bytes >= 2) align = 2;
256: else align = 1;
257: }
258: name = sprintf("__%smovstr%s%dx%d", us, mode, total + most, bytes + most);
259: if (bytes > most) {
260: printf "\tglobal\t%s\n", name;
261: printf "%s:\n", name;
262: }
263: if (bytes == 0)
264: printf "\tjmp.n\t%sr1\n", ps;
265: else
266: printf "\tld%s\t%sr%d,%sr3,%d\n", suffix[align], ps, 4 + evenp, ps, ld;
267: printf "\tst%s\t%sr%d,%sr2,%d\n", suffix[prev], ps, 5 - evenp, ps, st;
268: ld += align; st += prev; prev = align;
269: if (evenp)
270: evenp = 0;
271: else
272: evenp = 1;
273: }
274: if (!no_tdesc) {
275: printf "end%s%dx:\n", mode, total + most;
276: printf "\tsection\t.tdesc,\"%s\"\n", tf;
277: printf "\tword\t0x42\n";
278: printf "\tword\t1\n";
279: printf "\tword\t__%smovstr%s%dx%d\n", us, mode, total + most, total + most;
280: printf "\tword\tend%s%dx\n", mode, total + most;
281: printf "\tword\t0x0100001f\n";
282: printf "\tword\t0\n";
283: printf "\tword\t1\n";
284: printf "\tword\t0\n";
285: printf "\ttext\n";
286: }
287: printf "; End of awk generated code.\n"
288: exit;
289: }'
290: }
291:
292: (do_file '"movstrSI47x.s"';
293: echo 'SI:1:4:48' | gen_movstrXr) > moveSI47x.asm
294: (do_file '"movstrSI46x.s"';
295: echo 'SI:2:4:48' | gen_movstrXr) > moveSI46x.asm
296: (do_file '"movstrSI45x.s"';
297: echo 'SI:3:4:48' | gen_movstrXr) > moveSI45x.asm
298: (do_file '"movstrHI15x.s"';
299: echo 'HI:1:2:16' | gen_movstrXr) > moveHI15x.asm
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.