|
|
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 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.