|
|
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.