|
|
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: # ! 8: # This file provided by Data General, Feburary 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: # 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.