|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1986, 1987 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Mt. Xinu. ! 7: * ! 8: * Redistribution is only permitted until one year after the first shipment ! 9: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and ! 10: * binary forms are permitted provided that: (1) source distributions retain ! 11: * this entire copyright notice and comment, and (2) distributions including ! 12: * binaries display the following acknowledgement: This product includes ! 13: * software developed by the University of California, Berkeley and its ! 14: * contributors'' in the documentation or other materials provided with the ! 15: * distribution and in all advertising materials mentioning features or use ! 16: * of this software. Neither the name of the University nor the names of ! 17: * its contributors may be used to endorse or promote products derived from ! 18: * this software without specific prior written permission. ! 19: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 20: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 21: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 22: * ! 23: * @(#)emulate.s 7.5 (Berkeley) 6/28/90 ! 24: */ ! 25: ! 26: #if VAX630 || VAX650 ! 27: /* ! 28: * String instruction emulation - MicroVAX only. These routines are called ! 29: * from locore.s when an "emulate" fault occurs on the MicroVAX. They are ! 30: * called with the stack set up as follows: ! 31: * ! 32: * (sp): Return address of trap handler ! 33: * 4(sp): Instruction Opcode (also holds PSL result from emulator) ! 34: * 8(sp): Instruction PC ! 35: * 12(sp): Operand 1 ! 36: * 16(sp): Operand 2 ! 37: * 20(sp): Operand 3 ! 38: * 24(sp): Operand 4 ! 39: * 28(sp): Operand 5 ! 40: * 32(sp): Operand 6 ! 41: * 36(sp): old Register 11 ! 42: * 40(sp): old Register 10 ! 43: * 44(sp): Return PC ! 44: * 48(sp): Return PSL ! 45: * 52(sp): TOS before instruction ! 46: * ! 47: * R11 and r10 are available for use. If any routine needs to use r9-r1 ! 48: * they need to save them first (unless those registers are SUPPOSED to be ! 49: * messed with by the "instruction"). These routines leave their results ! 50: * in registers 0-5 explicitly, as needed, and use the macros defined below ! 51: * to link up with calling routine. ! 52: */ ! 53: ! 54: #define return rsb ! 55: #define savepsl movpsl 4(sp) ! 56: #define setpsl(reg) movl reg,4(sp) ! 57: #define overflowpsl movl $2,4(sp) ! 58: #define arg1 12(sp) ! 59: #define arg2 16(sp) ! 60: #define arg3 20(sp) ! 61: #define arg4 24(sp) ! 62: #define arg5 28(sp) ! 63: #define arg6 32(sp) ! 64: #define argub(num,reg) movzbl 8+4*num(sp),reg ! 65: #define arguw(num,reg) movzwl 8+4*num(sp),reg ! 66: #define argul(num,reg) movl 8+4*num(sp),reg ! 67: #define argb(num,reg) cvtbl 8+4*num(sp),reg ! 68: #define argw(num,reg) cvtwl 8+4*num(sp),reg ! 69: #define argl(num,reg) movl 8+4*num(sp),reg ! 70: #define toarg(reg,num) movl reg,8+4*num(sp) ! 71: ! 72: ! 73: .text ! 74: .align 1 ! 75: .globl _EMcrc ! 76: _EMcrc: ! 77: argl(1,r11) # (1) table address == r11 ! 78: argl(2,r0) # (2) initial crc == r0 ! 79: argl(4,r3) # (4) source address == r3 ! 80: arguw(3,r2) # (3) source length == r2 ! 81: jeql Lcrc_out ! 82: Lcrc_loop: ! 83: xorb2 (r3)+,r0 ! 84: extzv $0,$4,r0,r10 ! 85: extzv $4,$28,r0,r1 ! 86: xorl3 r1,(r11)[r10],r0 ! 87: extzv $0,$4,r0,r10 ! 88: extzv $4,$28,r0,r1 ! 89: xorl3 r1,(r11)[r10],r0 ! 90: sobgtr r2,Lcrc_loop ! 91: tstl r0 ! 92: Lcrc_out: ! 93: savepsl ! 94: clrl r1 ! 95: return ! 96: ! 97: ! 98: .align 1 ! 99: .globl _EMmovtc ! 100: _EMmovtc: ! 101: arguw(1,r0) # (1) source length == r0 ! 102: argl(2,r1) # (2) source address == r1 ! 103: argub(3,r11) # (3) fill character == r11 ! 104: argl(4,r3) # (4) table address == r3 ! 105: argl(6,r5) # (6) destination address == r5 ! 106: arguw(5,r4) # (5) destination length == r4 ! 107: jeql Lmovtc_out ! 108: Lmovtc_loop: ! 109: tstl r0 ! 110: jeql Lmovtc_2loop ! 111: movzbl (r1)+,r2 ! 112: movb (r3)[r2],(r5)+ ! 113: decl r0 ! 114: sobgtr r4,Lmovtc_loop ! 115: jbr Lmovtc_out ! 116: Lmovtc_2loop: ! 117: movb r11,(r5)+ ! 118: sobgtr r4,Lmovtc_2loop ! 119: Lmovtc_out: ! 120: cmpl r4,r0 ! 121: savepsl ! 122: clrl r2 ! 123: return ! 124: ! 125: ! 126: .align 1 ! 127: .globl _EMmovtuc ! 128: _EMmovtuc: ! 129: arguw(1,r0) # (1) source length == r0 ! 130: argl(2,r1) # (2) source address == r1 ! 131: argub(3,r11) # (3) escape character == r11 ! 132: argl(4,r3) # (4) table address == r3 ! 133: argl(6,r5) # (6) destination address == r5 ! 134: arguw(5,r4) # (5) destination length == r4 ! 135: jeql Lmovtuc_out ! 136: Lmovtuc_loop: ! 137: tstl r0 ! 138: jeql Lmovtuc_out ! 139: movzbl (r1),r2 ! 140: movzbl (r3)[r2],r2 ! 141: cmpl r2,r11 ! 142: jeql Lmovtuc_out ! 143: movzbl (r1)+,r2 ! 144: movb (r3)[r2],(r5)+ ! 145: decl r0 ! 146: sobgtr r4,Lmovtuc_loop ! 147: Lmovtuc_out: ! 148: cmpl r4,r0 ! 149: savepsl ! 150: clrl r2 ! 151: return ! 152: ! 153: ! 154: .align 1 ! 155: .globl _EMmatchc ! 156: _EMmatchc: ! 157: argl(2,r10) # (2) substring address == r10 ! 158: arguw(3,r2) # (3) source length == r2 ! 159: argl(4,r3) # (4) source address == r3 ! 160: arguw(1,r11) # (1) substring length == r11 ! 161: jeql Lmatchc_out # temp source address == r1 ! 162: addl2 r10,r11 # temp substring address == r0 ! 163: tstl r2 ! 164: jeql Lmatchc_out ! 165: Lmatchc_loop: ! 166: cmpb (r10),(r3) ! 167: jneq Lmatchc_fail ! 168: movl r3,r1 ! 169: movl r10,r0 ! 170: Lmatchc_2loop: ! 171: cmpl r0,r11 ! 172: jeql Lmatchc_succ ! 173: cmpb (r0)+,(r1)+ ! 174: jeql Lmatchc_2loop ! 175: Lmatchc_fail: ! 176: incl r3 ! 177: sobgtr r2,Lmatchc_loop ! 178: movl r10,r1 ! 179: subl3 r10,r11,r0 ! 180: jbr Lmatchc_out ! 181: Lmatchc_succ: ! 182: movl r1,r3 ! 183: movl r11,r1 ! 184: clrl r0 ! 185: Lmatchc_out: ! 186: savepsl ! 187: return ! 188: ! 189: ! 190: .align 1 ! 191: .globl _EMspanc ! 192: _EMspanc: ! 193: argl(2,r1) # (2) string address == r1 ! 194: argub(4,r2) # (4) character-mask == r2 ! 195: argl(3,r3) # (3) table address == r3 ! 196: arguw(1,r0) # (1) string length == r0 ! 197: jeql Lspanc_out ! 198: Lspanc_loop: ! 199: movzbl (r1),r11 ! 200: mcomb (r3)[r11],r11 ! 201: bicb3 r11,r2,r11 ! 202: jeql Lspanc_out ! 203: incl r1 ! 204: sobgtr r0,Lspanc_loop ! 205: Lspanc_out: ! 206: savepsl ! 207: clrl r2 ! 208: return ! 209: ! 210: ! 211: .align 1 ! 212: .globl _EMscanc ! 213: _EMscanc: ! 214: argl(2,r1) # (2) string address == r1 ! 215: argub(4,r2) # (4) character-mask == r2 ! 216: argl(3,r3) # (3) table address == r3 ! 217: arguw(1,r0) # (1) string length == r0 ! 218: jeql Lscanc_out ! 219: Lscanc_loop: ! 220: movzbl (r1),r11 ! 221: mcomb (r3)[r11],r11 ! 222: bicb3 r11,r2,r11 ! 223: jneq Lscanc_out ! 224: incl r1 ! 225: sobgtr r0,Lscanc_loop ! 226: Lscanc_out: ! 227: savepsl ! 228: clrl r2 ! 229: return ! 230: ! 231: ! 232: .align 1 ! 233: .globl _EMskpc ! 234: _EMskpc: ! 235: argub(1,r11) # (1) character == r11 ! 236: argl(3,r1) # (3) string address == r1 ! 237: arguw(2,r0) # (2) string length == r0 ! 238: jeql Lskpc_out # forget zero length strings ! 239: Lskpc_loop: ! 240: cmpb (r1),r11 ! 241: jneq Lskpc_out ! 242: incl r1 ! 243: sobgtr r0,Lskpc_loop ! 244: Lskpc_out: ! 245: tstl r0 # be sure of condition codes ! 246: savepsl ! 247: return ! 248: ! 249: ! 250: .align 1 ! 251: .globl _EMlocc ! 252: _EMlocc: ! 253: argub(1,r11) # (1) character == r11 ! 254: argl(3,r1) # (3) string address == r1 ! 255: arguw(2,r0) # (2) string length == r0 ! 256: jeql Lskpc_out # forget zero length strings ! 257: Llocc_loop: ! 258: cmpb (r1),r11 ! 259: jeql Llocc_out ! 260: incl r1 ! 261: sobgtr r0,Llocc_loop ! 262: Llocc_out: ! 263: tstl r0 # be sure of condition codes ! 264: savepsl ! 265: return ! 266: ! 267: ! 268: .align 1 ! 269: .globl _EMcmpc3 ! 270: _EMcmpc3: ! 271: argl(2,r1) # (2) string1 address == r1 ! 272: argl(3,r3) # (3) string2 address == r3 ! 273: arguw(1,r0) # (1) strings' length == r0 ! 274: jeql Lcmpc3_out ! 275: Lcmpc3_loop: ! 276: cmpb (r1),(r3) ! 277: jneq Lcmpc3_out ! 278: incl r1 ! 279: incl r3 ! 280: sobgtr r0,Lcmpc3_loop ! 281: Lcmpc3_out: ! 282: savepsl ! 283: movl r0,r2 ! 284: return ! 285: ! 286: ! 287: .align 1 ! 288: .globl _EMcmpc5 ! 289: _EMcmpc5: ! 290: argl(2,r1) # (2) string1 address == r1 ! 291: argub(3,r11) # (1) fill character == r11 ! 292: arguw(4,r2) # (1) string2 length == r2 ! 293: argl(5,r3) # (3) string2 address == r3 ! 294: arguw(1,r0) # (1) string1 length == r0 ! 295: jeql Lcmpc5_str2 ! 296: Lcmpc5_loop: ! 297: tstl r2 ! 298: jeql Lcmpc5_str1loop ! 299: cmpb (r1),(r3) ! 300: jneq Lcmpc5_out ! 301: incl r1 ! 302: incl r3 ! 303: decl r2 ! 304: sobgtr r0,Lcmpc5_loop ! 305: Lcmpc5_str2: ! 306: tstl r2 ! 307: jeql Lcmpc5_out ! 308: Lcmpc5_str2loop: ! 309: cmpb r11,(r3) ! 310: jneq Lcmpc5_out ! 311: incl r3 ! 312: sobgtr r2,Lcmpc5_str2loop ! 313: jbr Lcmpc5_out ! 314: Lcmpc5_str1loop: ! 315: cmpb (r1),r11 ! 316: jneq Lcmpc5_out ! 317: incl r1 ! 318: sobgtr r0,Lcmpc5_str1loop ! 319: Lcmpc5_out: ! 320: savepsl ! 321: return ! 322: ! 323: ! 324: /* ! 325: * Packed Decimal string operations ! 326: */ ! 327: ! 328: #define POSITIVE $12 ! 329: #define NEGATIVE $13 ! 330: #define NEGATIVEalt $11 ! 331: ! 332: ! 333: .align 1 ! 334: .globl _EMaddp4 ! 335: _EMaddp4: ! 336: toarg(r9,6) # save register r9 in arg6 spot ! 337: arguw(1,r11) # (1) source length == r11 ! 338: argl(2,r10) # (2) source address == r10 ! 339: arguw(3,r9) # (3) destination length == r9 ! 340: argl(4,r3) # (4) destination address == r3 ! 341: # arg4 will be needed later ! 342: # arg5 holds destination address of LSNibble temporarily ! 343: ashl $-1,r11,r11 ! 344: addl2 r11,r10 # source address of LSNibble ! 345: incl r11 # source length is in bytes ! 346: ashl $-1,r9,r9 ! 347: addl2 r9,r3 # r3 = destination address of LSNibble ! 348: incl r9 # destination length is in bytes ! 349: toarg(r3,5) # stored in arg5 spot ! 350: extzv $0,$4,(r3),r2 # set standard +/- indicators in destination ! 351: cmpl r2,NEGATIVE ! 352: jeql L112 ! 353: cmpl r2,NEGATIVEalt ! 354: jeql L111 ! 355: insv POSITIVE,$0,$4,(r3) ! 356: jbr L112 ! 357: L111: ! 358: insv NEGATIVE,$0,$4,(r3) ! 359: L112: ! 360: extzv $0,$4,(r10),r2 # r2 = standard +/- of source ! 361: cmpl r2,NEGATIVE ! 362: jeql L114 ! 363: cmpl r2,NEGATIVEalt ! 364: jeql L113 ! 365: movl POSITIVE,r2 ! 366: jbr L114 ! 367: L113: ! 368: movl NEGATIVE,r2 ! 369: L114: ! 370: cmpl r11,r9 # if source is longer than destination ! 371: jleq L115 ! 372: movl r9,r11 # set source length == destination length ! 373: L115: ! 374: extzv $4,$4,(r3),r9 # r9 = LSDigit of destination ! 375: extzv $4,$4,(r10),r1 # r1 = LSDigit of source ! 376: extzv $0,$4,(r3),r0 ! 377: cmpl r0,r2 # if signs of operands are not equal ! 378: jeql Laddp4_same # do a subtraction ! 379: clrl r2 # r2 is non-zero if result is non-zero ! 380: subl2 r1,r9 # r9 = "addition" of operands' high nibble ! 381: jbr L119 # jump into addition loop ! 382: Laddp4_diff_loop: ! 383: decl r3 ! 384: extzv $0,$4,(r3),r0 ! 385: addl2 r0,r1 # r1 = carry + next (low) nibble of source ! 386: decl r10 ! 387: extzv $0,$4,(r10),r0 ! 388: subl2 r0,r1 # r1 -= next (low) nibble of destination ! 389: jgeq L121 # if negative result ! 390: mnegl $1,r9 # r9 == carry = -1 ! 391: addl2 $10,r1 # r1 == result += 10 ! 392: jbr L122 # else ! 393: L121: ! 394: clrl r9 # r9 == carry = 0 ! 395: L122: ! 396: insv r1,$0,$4,(r3) # store result low nibble ! 397: bisl2 r1,r2 ! 398: extzv $4,$4,(r3),r0 ! 399: addl2 r0,r9 # r9 = carry + next (high) nibble of source ! 400: extzv $4,$4,(r10),r0 ! 401: subl2 r0,r9 # r9 -= next (high) nibble of destination ! 402: L119: ! 403: jgeq L117 # if negative result ! 404: mnegl $1,r1 # r1 == carry = -1 ! 405: addl2 $10,r9 # r9 == result += 10 ! 406: jbr L118 # else ! 407: L117: ! 408: clrl r1 # r1 == carry = 0 ! 409: L118: ! 410: insv r9,$4,$4,(r3) # store result high nibble ! 411: bisl2 r9,r2 # r2 is non-zero if result is non-zero ! 412: decl r11 # while (--source length) ! 413: jneq Laddp4_diff_loop ! 414: argl(4,r10) # r10 = address of destination MSNibble ! 415: jbr Laddp4_diff_carry ! 416: Laddp4_diff_carlop: ! 417: decl r3 ! 418: extzv $0,$4,(r3),r0 ! 419: addl2 r0,r1 # r1 == carry += next (low) nibble ! 420: jgeq L127 # if less than zero ! 421: movl r1,r9 # r9 == carry (must be -1) ! 422: movl $9,r1 # r1 == result = 9 ! 423: jbr L128 ! 424: L127: # else ! 425: clrl r9 # r9 == carry = 0 ! 426: L128: ! 427: insv r1,$0,$4,(r3) # store result ! 428: bisl2 r1,r2 ! 429: extzv $4,$4,(r3),r0 ! 430: addl2 r0,r9 # r9 == carry += next (high) nibble ! 431: jgeq L129 # if less than zero ! 432: movl r9,r1 # r1 == carry (must be -1) ! 433: movl $9,r9 # r9 == result = 9 ! 434: jbr L130 ! 435: L129: ! 436: clrl r1 ! 437: L130: ! 438: insv r9,$4,$4,(r3) # store result ! 439: bisl2 r9,r2 ! 440: Laddp4_diff_carry: ! 441: cmpl r3,r10 ! 442: jneq Laddp4_diff_carlop ! 443: tstl r1 # if carry out of MSN then fix up result ! 444: jeql Laddp4_add_done ! 445: argl(5,r3) # r3 == address of LSN of destination ! 446: extzv $0,$4,(r3),r0 ! 447: cmpl r0,NEGATIVE # switch sign of result ! 448: jneq L132 ! 449: insv POSITIVE,$0,$4,(r3) ! 450: jbr L133 ! 451: L132: ! 452: insv NEGATIVE,$0,$4,(r3) ! 453: L133: ! 454: extzv $4,$4,(r3),r0 # normalize result (carry out of MSN into LSN) ! 455: subl3 r0,$10,r9 # r9 = 10 - destination LSNibble ! 456: jbr L134 ! 457: L137: ! 458: movl $9,r1 ! 459: Laddp4_diff_norm: ! 460: insv r9,$4,$4,(r3) ! 461: cmpl r3,r10 # while (not at MSNibble) ! 462: jeql Laddp4_add_done ! 463: decl r3 ! 464: extzv $0,$4,(r3),r0 # low nibble = (9 + carry) - low nibble ! 465: subl2 r0,r1 ! 466: cmpl r1,$9 ! 467: jleq L135 ! 468: clrl r1 ! 469: movl $10,r9 ! 470: jbr L136 ! 471: L135: ! 472: movl $9,r9 ! 473: L136: ! 474: insv r1,$0,$4,(r3) ! 475: extzv $4,$4,(r3),r0 # high nibble = (9 + carry) - high nibble ! 476: subl2 r0,r9 ! 477: L134: ! 478: cmpl r9,$9 ! 479: jleq L137 ! 480: clrl r9 ! 481: movl $10,r1 ! 482: jbr Laddp4_diff_norm ! 483: ! 484: Laddp4_same: # operands are of the same sign ! 485: clrl r2 ! 486: addl2 r1,r9 ! 487: jbr L139 ! 488: Laddp4_same_loop: ! 489: decl r3 ! 490: extzv $0,$4,(r3),r0 ! 491: addl2 r0,r1 # r1 == carry += next (low) nibble of dest ! 492: decl r10 ! 493: extzv $0,$4,(r10),r0 ! 494: addl2 r0,r1 # r1 += next (low) nibble of source ! 495: cmpl r1,$9 # if result > 9 ! 496: jleq L141 ! 497: movl $1,r9 # r9 == carry = 1 ! 498: subl2 $10,r1 # r1 == result -= 10 ! 499: jbr L142 ! 500: L141: # else ! 501: clrl r9 # r9 == carry = 0 ! 502: L142: ! 503: insv r1,$0,$4,(r3) # store result ! 504: bisl2 r1,r2 ! 505: extzv $4,$4,(r10),r0 ! 506: addl2 r0,r9 # ditto for high nibble ! 507: extzv $4,$4,(r3),r0 ! 508: addl2 r0,r9 ! 509: L139: ! 510: cmpl r9,$9 ! 511: jleq L143 ! 512: movl $1,r1 ! 513: subl2 $10,r9 ! 514: jbr L144 ! 515: L143: ! 516: clrl r1 ! 517: L144: ! 518: insv r9,$4,$4,(r3) ! 519: bisl2 r9,r2 ! 520: sobgtr r11,Laddp4_same_loop # while (--source length) ! 521: argl(4,r10) # r10 = destination address of MSNibble ! 522: jbr Laddp4_same_carry ! 523: Laddp4_same_cloop: ! 524: decl r3 ! 525: extzv $0,$4,(r3),r0 # propagate carry up to MSNibble of destination ! 526: addl2 r0,r1 ! 527: cmpl r1,$10 ! 528: jneq L147 ! 529: movl $1,r9 ! 530: clrl r1 ! 531: jbr L148 ! 532: L147: ! 533: clrl r9 ! 534: L148: ! 535: insv r1,$0,$4,(r3) ! 536: bisl2 r1,r2 ! 537: extzv $4,$4,(r3),r0 ! 538: addl2 r0,r9 ! 539: cmpl r9,$10 ! 540: jneq L149 ! 541: movl $1,r1 ! 542: clrl r9 ! 543: jbr L150 ! 544: L149: ! 545: clrl r1 ! 546: L150: ! 547: insv r9,$4,$4,(r3) ! 548: bisl2 r9,r2 ! 549: Laddp4_same_carry: ! 550: cmpl r3,r10 ! 551: jneq Laddp4_same_cloop ! 552: ! 553: Laddp4_add_done: ! 554: argl(5,r3) # r3 = destination address of LSNibble ! 555: tstl r2 # if zero result ! 556: jneq L151 ! 557: savepsl # remember that for condition codes ! 558: insv POSITIVE,$0,$4,(r3) # make sure sign of result is positive ! 559: jbr Laddp4_out ! 560: L151: # else ! 561: extzv $0,$4,(r3),r0 ! 562: cmpl r0,NEGATIVE # if result is negative ! 563: jneq Laddp4_out ! 564: mnegl r2,r2 # remember THAT in Cond Codes ! 565: savepsl ! 566: Laddp4_out: ! 567: argl(4,r3) ! 568: argl(2,r1) ! 569: clrl r0 ! 570: clrl r2 ! 571: argl(6,r9) # restore r9 from stack ! 572: return ! 573: ! 574: ! 575: .align 1 ! 576: .globl _EMmovp ! 577: _EMmovp: ! 578: arguw(1,r11) # (1) string length == r11 ! 579: argl(2,r10) # (1) source address == r10 ! 580: argl(3,r3) # (1) destination address == r3 ! 581: # we will need arg2 and arg3 later ! 582: clrl r2 # r2 == non-zero if source is non-zero ! 583: ashl $-1,r11,r11 # length is number of bytes, not nibbles ! 584: jeql Lmovp_zlen ! 585: Lmovp_copy: ! 586: bisb2 (r10),r2 # keep track of non-zero source ! 587: movb (r10)+,(r3)+ # move two nibbles ! 588: sobgtr r11,Lmovp_copy # loop for length of source ! 589: Lmovp_zlen: ! 590: extzv $4,$4,(r10),r0 # look at least significant nibble ! 591: bisl2 r0,r2 ! 592: extzv $0,$4,(r10),r0 # check sign nibble ! 593: cmpl r0,NEGATIVEalt ! 594: jeql Lmovp_neg ! 595: cmpl r0,NEGATIVE ! 596: jneq Lmovp_pos ! 597: Lmovp_neg: # source was negative ! 598: mnegl r2,r2 ! 599: Lmovp_pos: ! 600: tstl r2 # set condition codes ! 601: savepsl ! 602: jeql Lmovp_zero ! 603: movb (r10),(r3) # move last byte if non-zero result ! 604: jbr Lmovp_out ! 605: Lmovp_zero: ! 606: movb POSITIVE,(r3) # otherwise, make result zero and positive ! 607: Lmovp_out: ! 608: clrl r0 ! 609: argl(2,r1) ! 610: clrl r2 ! 611: argl(3,r3) ! 612: return ! 613: ! 614: ! 615: /* ! 616: * Definitions for Editpc instruction ! 617: * ! 618: * Here are the commands and their corresponding hex values: ! 619: * ! 620: * EPend 0x00 ! 621: * EPend_float 0x01 ! 622: * EPclear_signif 0x02 ! 623: * EPset_signif 0x03 ! 624: * EPstore_sign 0x04 ! 625: * EPload_fill 0x40 ! 626: * EPload_sign 0x41 ! 627: * EPload_plus 0x42 ! 628: * EPload_minus 0x43 ! 629: * EPinsert 0x44 ! 630: * EPblank_zero 0x45 ! 631: * EPreplace_sign 0x46 ! 632: * EPadjust_input 0x47 ! 633: * EPfill 0x80 ! 634: * EPmove 0x90 ! 635: * EPfloat 0xa0 ! 636: * ! 637: * ! 638: * r4 is carved up as follows: ! 639: * ! 640: * ------------------------------------------- ! 641: * | N Z V C | ! 642: * ------------------------------------------- ! 643: * ! 644: * fill character is stuffed into arg5 space ! 645: * sign character is stuffed into arg6 space ! 646: */ ! 647: ! 648: #define SIGNIFBIT $0 ! 649: #define setsignif bisl2 $1,r4 ! 650: #define clsignif bicl2 $1,r4 ! 651: #define OVERFLOWBIT $1 ! 652: #define setoverflow bisl2 $2,r4 ! 653: #define cloverflow bicl2 $2,r4 ! 654: #define ZEROBIT $2 ! 655: #define setzero bisl2 $4,r4 ! 656: #define clzero bicl2 $4,r4 ! 657: #define NEGATIVEBIT $3 ! 658: #define setnegative bisl2 $8,r4 ! 659: #define clnegative bicl2 $8,r4 ! 660: #define putfill movb arg5,(r5)+ ! 661: #define setfill(reg) movb reg,arg5 ! 662: #define putsign movb arg6,(r5)+ ! 663: #define setsign(reg) movb reg,arg6 ! 664: ! 665: ! 666: .align 1 ! 667: .globl _EMeditpc ! 668: _EMeditpc: ! 669: arguw(1,r11) # (1) source length == r11 ! 670: argl(2,r10) # (2) source address == r10 ! 671: argl(3,r3) # (3) pattern address == r3 ! 672: argl(4,r5) # (4) destination address == r5 ! 673: # we will need arg1 and arg2 later ! 674: # arg5 and arg6 are used for fill and sign - r0 is free ! 675: setfill($32) # fill character is ' ' ! 676: setsign($32) # sign character is ' ' ! 677: clrl r4 # clear flags ! 678: ashl $-1,r11,r11 # source length / 2 ! 679: addl3 r11,r10,r2 ! 680: extzv $4,$4,(r2),r1 # r1 == least significant nibble of source ! 681: L169: ! 682: cmpl r2,r10 ! 683: jeql L170 ! 684: tstb -(r2) # loop over source packed decimal number ! 685: jeql L169 ! 686: incl r1 # r1 is non-zero if source is non-zero ! 687: L170: ! 688: addl3 r11,r10,r2 ! 689: tstl r1 ! 690: jeql L172 # source is zero - set flags ! 691: extzv $0,$4,(r2),r11 ! 692: cmpl r11,NEGATIVEalt ! 693: jeql L9998 # source is negative - set sign and flags ! 694: cmpl r11,NEGATIVE ! 695: jneq L175 ! 696: L9998: ! 697: setnegative ! 698: setsign($45) # sign character is '-' ! 699: jbr L175 ! 700: L172: ! 701: setzero ! 702: L175: ! 703: arguw(1,r2) # (1) source length == r2 ! 704: Ledit_case: ! 705: movzbl (r3)+,r11 # get next edit command (pattern) ! 706: cmpl r11,$128 ! 707: jlss L180 ! 708: extzv $0,$4,r11,r1 # command has a "count" arg - into r1 ! 709: ashl $-4,r11,r11 # and shift over ! 710: L180: ! 711: jbc $6,r11,L181 # "shift" those commands > 64 to 16 and up ! 712: subl2 $48,r11 ! 713: L181: ! 714: caseb r11,$0,$0x18 # "do" the command ! 715: # r11 is available for use, r1 has "count" in it ! 716: Lcaseb_label: ! 717: .word Le_end - Lcaseb_label # 00 ! 718: .word Le_end_float - Lcaseb_label # 01 ! 719: .word Le_clear_signif - Lcaseb_label # 02 ! 720: .word Le_set_signif - Lcaseb_label # 03 ! 721: .word Le_store_sign - Lcaseb_label # 04 ! 722: .word Le_end - Lcaseb_label # 05 ! 723: .word Le_end - Lcaseb_label # 06 ! 724: .word Le_end - Lcaseb_label # 07 ! 725: .word Le_fill - Lcaseb_label # 80 ! 726: .word Le_move - Lcaseb_label # 90 ! 727: .word Le_float - Lcaseb_label # a0 ! 728: .word Le_end - Lcaseb_label # b0 ! 729: .word Le_end - Lcaseb_label # c0 ! 730: .word Le_end - Lcaseb_label # d0 ! 731: .word Le_end - Lcaseb_label # e0 ! 732: .word Le_end - Lcaseb_label # f0 ! 733: .word Le_load_fill - Lcaseb_label # 40 ! 734: .word Le_load_sign - Lcaseb_label # 41 ! 735: .word Le_load_plus - Lcaseb_label # 42 ! 736: .word Le_load_minus - Lcaseb_label # 43 ! 737: .word Le_insert - Lcaseb_label # 44 ! 738: .word Le_blank_zero - Lcaseb_label # 45 ! 739: .word Le_replace_sign - Lcaseb_label # 46 ! 740: .word Le_adjust_input - Lcaseb_label # 47 ! 741: Le_end: ! 742: arguw(1,r0) ! 743: argl(2,r1) ! 744: clrl r2 ! 745: decl r3 ! 746: setpsl(r4) ! 747: clrl r4 ! 748: return ! 749: ! 750: Le_end_float: ! 751: jbs SIGNIFBIT,r4,Ledit_case # if significance not set ! 752: putsign # drop in the sign ! 753: # fall into... ! 754: Le_set_signif: ! 755: setsignif ! 756: jbr Ledit_case ! 757: ! 758: Le_clear_signif: ! 759: clsignif ! 760: jbr Ledit_case ! 761: ! 762: Le_store_sign: ! 763: putsign ! 764: jbr Ledit_case ! 765: ! 766: Le_load_fill: ! 767: setfill((r3)+) ! 768: jbr Ledit_case ! 769: ! 770: Le_load_plus: ! 771: jbs NEGATIVEBIT,r4,Lpattern_inc # if non-negative ! 772: # fall into... ! 773: Le_load_sign: ! 774: setsign((r3)+) ! 775: jbr Ledit_case ! 776: ! 777: Le_load_minus: ! 778: jbs NEGATIVEBIT,r4,Le_load_sign # if negative load the sign ! 779: incl r3 # else increment pattern ! 780: jbr Ledit_case ! 781: ! 782: Le_insert: ! 783: jbc SIGNIFBIT,r4,L196 # if significance set, put next byte ! 784: movb (r3)+,(r5)+ ! 785: jbr Ledit_case ! 786: L196: # else put in fill character ! 787: putfill ! 788: # and throw away character in pattern ! 789: Le_replace_sign: # we don't do anything with ! 790: Lpattern_inc: # replace sign `cause we don't ! 791: incl r3 # get negative zero ! 792: jbr Ledit_case ! 793: ! 794: Le_blank_zero: ! 795: jbc ZEROBIT,r4,Lpattern_inc # if zero ! 796: movzbl (r3)+,r11 # next byte is a count ! 797: jeql Ledit_case ! 798: subl2 r11,r5 # to back up over output and replace ! 799: L200: ! 800: putfill # with fill character ! 801: sobgtr r11,L200 ! 802: jbr Ledit_case ! 803: ! 804: Le_adjust_input: ! 805: movzbl (r3)+,r0 # get count of nibbles from pattern ! 806: subl3 r2,r0,r11 ! 807: jgeq Ledit_case # if length of source is > this number ! 808: L204: # discard digits in source ! 809: jlbc r2,L206 # use low bit of length to choose nibble ! 810: bitb $0xf0,(r10) # high nibble ! 811: jeql L208 ! 812: setsignif # set significance and overflow if ! 813: setoverflow # wasted digit is non-zero ! 814: jbr L208 ! 815: L206: ! 816: bitb $0xf,(r10) # low nibble ! 817: jeql L209 ! 818: setsignif ! 819: setoverflow ! 820: L209: ! 821: incl r10 # increment to next byte ! 822: L208: ! 823: decl r2 # decrement source length ! 824: incl r11 # continue `till we're out of excess ! 825: jlss L204 ! 826: jbr Ledit_case ! 827: ! 828: Le_fill: ! 829: tstl r1 # put (count in r1) fill characters ! 830: jeql Ledit_case ! 831: Le_fill_loop: ! 832: putfill ! 833: sobgtr r1,Le_fill_loop ! 834: jbr Ledit_case ! 835: ! 836: Le_move: ! 837: tstl r1 # move (count in r1) characters ! 838: jeql Ledit_case # from source to destination ! 839: L214: ! 840: jlbc r2,L215 # read a nibble ! 841: extzv $4,$4,(r10),r11 ! 842: jbr L216 ! 843: L215: ! 844: extzv $0,$4,(r10),r11 ! 845: incl r10 ! 846: L216: ! 847: decl r2 # source length CAN go negative here... ! 848: tstl r11 ! 849: jeql L218 # if non-zero ! 850: setsignif # set significance ! 851: L218: ! 852: jbc SIGNIFBIT,r4,L219 # if significance set ! 853: addb3 $48,r11,(r5)+ # put '0' + digit into destination ! 854: jbr L220 ! 855: L219: # else put fill character ! 856: putfill ! 857: L220: ! 858: sobgtr r1,L214 ! 859: jbr Ledit_case ! 860: ! 861: Le_float: # move with floating sign character ! 862: tstl r1 ! 863: jeql Ledit_case ! 864: L221: ! 865: jlbc r2,L222 ! 866: extzv $4,$4,(r10),r11 ! 867: jbr L223 ! 868: L222: ! 869: extzv $0,$4,(r10),r11 ! 870: incl r10 ! 871: L223: ! 872: decl r2 # source length CAN go negative here... ! 873: tstl r11 ! 874: jeql L225 ! 875: jbs SIGNIFBIT,r4,L226 ! 876: putsign ! 877: L226: ! 878: setsignif ! 879: L225: ! 880: jbc SIGNIFBIT,r4,L227 ! 881: addb3 $48,r11,(r5)+ ! 882: jbr L228 ! 883: L227: ! 884: putfill ! 885: L228: ! 886: sobgtr r1,L221 ! 887: jbr Ledit_case ! 888: ! 889: ! 890: .align 1 ! 891: .globl _EMashp ! 892: _EMashp: ! 893: argb(1,r11) # (1) scale (number to shift) == r11 ! 894: arguw(2,r10) # (2) source length == r10 ! 895: argl(3,r1) # (3) source address == r1 ! 896: argub(4,r2) # (4) rounding factor == r2 ! 897: arguw(5,r3) # (5) destination length == r3 ! 898: toarg(r6,3) # arg3 holds register 6 from caller ! 899: argl(6,r6) # (6) destination address == r6 ! 900: # we need arg6 for later ! 901: # arg1 is used for temporary storage ! 902: # arg2 holds "even or odd" destination length ! 903: # arg4 is used as general storage ! 904: # arg5 is used as general storage ! 905: ashl $-1,r3,r0 # destination length is number of bytes ! 906: addl2 r0,r6 # destination address == least sig nibble ! 907: toarg(r6,1) # save in arg1 spot for later ! 908: ashl $-1,r10,r0 ! 909: addl2 r0,r1 # source address == least sig nibble ! 910: extzv $0,$4,(r1),r0 # determine sign of source ! 911: cmpl r0,NEGATIVEalt ! 912: jeql Lashp_neg ! 913: cmpl r0,NEGATIVE ! 914: jeql Lashp_neg ! 915: movb POSITIVE,(r6) ! 916: jbr L245 ! 917: Lashp_neg: ! 918: movb NEGATIVE,(r6) ! 919: L245: ! 920: clrl arg2 # arg2 is 1 if dstlen is even, 0 if odd ! 921: blbs r3,L246 ! 922: incl arg2 ! 923: bisl2 $1,r3 # r3<0> counts digits going into destination ! 924: L246: # and is flip-flop for which nibble to ! 925: tstl r11 # write in destination (1 = high, 0 = low) ! 926: jgeq Lashp_left # (it must start out odd) ! 927: addl2 r11,r10 # scale is negative (right shift) ! 928: jgeq Lashp_right ! 929: clrl r10 # test for shifting whole number out ! 930: jbr Lashp_setround ! 931: Lashp_right: ! 932: divl3 $2,r11,r0 ! 933: addl2 r0,r1 # source address == MSNibble to be shifted off ! 934: jlbc r11,L249 ! 935: extzv $4,$4,(r1),r0 ! 936: addl2 r0,r2 # round = last nibble to be shifted off + round ! 937: jbr Lashp_setround ! 938: L249: ! 939: extzv $0,$4,(r1),r0 ! 940: addl2 r0,r2 # round = last nibble to be shifted off + round ! 941: Lashp_setround: # r11<0> now is flip-flop for which nibble to ! 942: incl r11 # read from source (1 == high, 0 == low) ! 943: cmpl r2,$9 # set rounding factor to one if nibble shifted ! 944: jleq Lashp_noround # off + round argument was 10 or greater ! 945: movl $1,r2 ! 946: jbr Lashp_shift ! 947: Lashp_zloop: ! 948: jlbs r3,L257 # don't need to clear high nibble twice ! 949: clrb -(r6) # clear low (and high) nib of next byte in dest ! 950: L257: ! 951: sobgtr r3,L258 # move to next nibble in destination, but ! 952: incl r3 # don't go beyond the end. ! 953: L258: ! 954: decl r11 ! 955: Lashp_left: # while scale is positive ! 956: jneq Lashp_zloop ! 957: incl r11 # r11<0> is flip-plop ... (incl sets it to one) ! 958: Lashp_noround: ! 959: clrl r2 # no more rounding ! 960: Lashp_shift: ! 961: clrl arg4 # arg4 will be used for result condition codes ! 962: tstl r10 ! 963: jeql Lashp_round ! 964: Lashp_shloop: ! 965: jlbc r11,L260 ! 966: extzv $4,$4,(r1),r0 ! 967: jbr L261 ! 968: L260: ! 969: decl r1 ! 970: extzv $0,$4,(r1),r0 ! 971: L261: ! 972: incl r11 # flip the source nibble flip/flop ! 973: addl2 r0,r2 # round += next nibble ! 974: cmpl r2,$10 # if round == 10 ! 975: jneq L262 ! 976: clrl arg5 # then result = 0 and round = 1 ! 977: movl $1,r2 ! 978: jbr L263 ! 979: L262: # else ! 980: movl r2,arg5 # store result and round = 0 ! 981: clrl r2 ! 982: L263: ! 983: bisl2 arg5,arg4 # remember if result was nonzero in arg4 ! 984: decl r3 # move to next nibble early to check ! 985: cmpl r3,arg2 # if we've moved passed destination limits ! 986: jgeq Lashp_noovfl # test the result for possible overflow ! 987: movl arg2,r3 # ignore zero nibbles ! 988: tstl arg5 # if the nibble was non-zero, overflow ! 989: jeql L265 ! 990: jbr Lashp_overfl ! 991: Lashp_noovfl: # else ! 992: jlbs r3,L264 ! 993: insv arg5,$4,$4,(r6) # put the result into destination (high or low) ! 994: jbr L265 ! 995: L264: ! 996: movb arg5,-(r6) ! 997: L265: ! 998: sobgtr r10,Lashp_shloop # loop for length of source ! 999: ! 1000: Lashp_round: ! 1001: tstl r2 # take care of round out of high nibble ! 1002: jeql Lashp_zeroround ! 1003: decl r3 ! 1004: cmpl r3,arg2 # if we've moved passed destination limits ! 1005: jlss Lashp_overfl # then overflow ! 1006: jlbs r3,L266 ! 1007: insv arg5,$4,$4,(r6) # put the round into destination (high or low) ! 1008: jbr Lashp_zeroround ! 1009: L266: ! 1010: movb arg5,-(r6) ! 1011: ! 1012: Lashp_zeroround: ! 1013: argl(1,r10) # r10 = address of destination LSNibble ! 1014: argl(6,r3) # r3 = address of destination MSNibble ! 1015: movl arg4,r11 # r11 = non-zero if destination == non-zero ! 1016: savepsl ! 1017: jbr L267 ! 1018: Lashp_zerofill: ! 1019: clrb -(r6) # fill up MSNs of destination with zeros ! 1020: L267: ! 1021: cmpl r3,r6 ! 1022: jneq Lashp_zerofill ! 1023: extzv $0,$4,(r10),r0 # test for negative result ! 1024: cmpl r0,NEGATIVE ! 1025: jneq Lashp_out ! 1026: mnegl r11,r11 ! 1027: savepsl ! 1028: jneq Lashp_out # turn -0 into 0 ! 1029: insv POSITIVE,$0,$4,(r10) ! 1030: Lashp_out: ! 1031: clrl r0 ! 1032: argl(3,r6) # restore r6 from stack ! 1033: return ! 1034: Lashp_overfl: # do overflow ! 1035: clrl r2 ! 1036: overflowpsl ! 1037: jbr Lashp_out ! 1038: ! 1039: ! 1040: .align 1 ! 1041: .globl _EMcvtlp ! 1042: _EMcvtlp: ! 1043: arguw(2,r10) # (2) destination length == r10 ! 1044: argl(3,r3) # (3) destination address == r3 ! 1045: ashl $-1,r10,r10 ! 1046: addl2 r10,r3 # destination address points to Least Sig byte ! 1047: incl r10 # length is # of bytes, not nibbles ! 1048: argl(1,r11) # (1) source == r11 ! 1049: savepsl ! 1050: jgeq Lcvtlp_pos ! 1051: movb NEGATIVE,(r3) # source is negative ! 1052: divl3 $10,r11,r0 ! 1053: mull3 $10,r0,r1 ! 1054: subl3 r11,r1,r2 # r2 = source mod 10 ! 1055: mnegl r0,r11 # source = -(source / 10) ! 1056: jbr Lcvtlp_cvt ! 1057: Lcvtlp_pos: ! 1058: movb POSITIVE,(r3) # source is non-negative ! 1059: divl3 $10,r11,r0 ! 1060: mull3 $10,r0,r1 ! 1061: subl3 r1,r11,r2 # r2 = source mod 10 ! 1062: movl r0,r11 # source = source / 10 ! 1063: Lcvtlp_cvt: ! 1064: insv r2,$4,$4,(r3) # store least significant digit ! 1065: tstl r11 ! 1066: jeql Lcvtlp_zloop ! 1067: Lcvtlp_loop: # while source is non-zero ! 1068: decl r10 # and for length of destination ... ! 1069: jeql Lcvtlp_over ! 1070: divl3 $10,r11,r1 # r1 = source / 10 ! 1071: mull3 $10,r1,r0 ! 1072: subl2 r0,r11 # source = source mod 10 ! 1073: movb r11,-(r3) # store low "nibble" in next significant byte ! 1074: divl3 $10,r1,r11 # source = r1 / 10 ! 1075: mull3 $10,r11,r0 ! 1076: subl2 r0,r1 # r1 = source mod 10 ! 1077: insv r1,$4,$4,(r3) # store high nibble ! 1078: tstl r11 ! 1079: jneq Lcvtlp_loop # quit if source becomes zero ! 1080: Lcvtlp_zloop: # fill any remaining bytes with zeros ! 1081: decl r10 ! 1082: jeql Lcvtlp_out ! 1083: clrb -(r3) ! 1084: jbr Lcvtlp_zloop ! 1085: Lcvtlp_over: ! 1086: overflowpsl ! 1087: Lcvtlp_out: ! 1088: clrl r1 # r0 is already zero ! 1089: clrl r2 ! 1090: return ! 1091: ! 1092: ! 1093: .align 1 ! 1094: .globl _EMcvtpl ! 1095: _EMcvtpl: ! 1096: arguw(1,r11) # (1) source length == r11 ! 1097: argl(2,r10) # (2) source address == r10 ! 1098: clrl r3 # r3 == destination ! 1099: movl r10,r1 # r1 set up now for return ! 1100: ashl $-1,r11,r11 # source length is number of bytes ! 1101: jeql Lcvtpl_zero ! 1102: Lcvtpl_loop: # for source length ! 1103: mull2 $10,r3 # destination *= 10 ! 1104: extzv $4,$4,(r10),r0 ! 1105: addl2 r0,r3 # destination += high nibble ! 1106: mull2 $10,r3 # destination *= 10 ! 1107: extzv $0,$4,(r10),r0 ! 1108: addl2 r0,r3 # destination += low nibble ! 1109: incl r10 ! 1110: sobgtr r11,Lcvtpl_loop ! 1111: Lcvtpl_zero: # least significant byte ! 1112: mull2 $10,r3 ! 1113: extzv $4,$4,(r10),r0 ! 1114: addl2 r0,r3 # dest = 10 * dest + high nibble ! 1115: savepsl ! 1116: extzv $0,$4,(r10),r2 # test sign nibble ! 1117: cmpl r2,NEGATIVE ! 1118: jeql Lcvtpl_neg ! 1119: cmpl r2,NEGATIVEalt ! 1120: jneq Lcvtpl_out ! 1121: Lcvtpl_neg: # source was negative - negate destination ! 1122: mnegl r3,r3 ! 1123: savepsl ! 1124: Lcvtpl_out: ! 1125: toarg(r3,3) ! 1126: clrl r0 ! 1127: clrl r2 ! 1128: clrl r3 ! 1129: return ! 1130: ! 1131: ! 1132: .align 1 ! 1133: .globl _EMcvtps ! 1134: _EMcvtps: ! 1135: return ! 1136: ! 1137: ! 1138: .align 1 ! 1139: .globl _EMcvtsp ! 1140: _EMcvtsp: ! 1141: return ! 1142: ! 1143: ! 1144: .align 1 ! 1145: .globl _EMaddp6 ! 1146: _EMaddp6: ! 1147: return ! 1148: ! 1149: ! 1150: .align 1 ! 1151: .globl _EMsubp4 ! 1152: _EMsubp4: ! 1153: return ! 1154: ! 1155: ! 1156: .align 1 ! 1157: .globl _EMsubp6 ! 1158: _EMsubp6: ! 1159: return ! 1160: ! 1161: ! 1162: .align 1 ! 1163: .globl _EMcvtpt ! 1164: _EMcvtpt: ! 1165: return ! 1166: ! 1167: ! 1168: .align 1 ! 1169: .globl _EMmulp ! 1170: _EMmulp: ! 1171: return ! 1172: ! 1173: ! 1174: .align 1 ! 1175: .globl _EMcvttp ! 1176: _EMcvttp: ! 1177: return ! 1178: ! 1179: ! 1180: .align 1 ! 1181: .globl _EMdivp ! 1182: _EMdivp: ! 1183: return ! 1184: ! 1185: ! 1186: .align 1 ! 1187: .globl _EMcmpp3 ! 1188: _EMcmpp3: ! 1189: return ! 1190: ! 1191: ! 1192: .align 1 ! 1193: .globl _EMcmpp4 ! 1194: _EMcmpp4: ! 1195: return ! 1196: ! 1197: ! 1198: #endif UVAXII ! 1199: ! 1200: ! 1201: #ifdef notdef ! 1202: /* ! 1203: * Emulation OpCode jump table: ! 1204: * ONLY GOES FROM 0xf8 (-8) TO 0x3B (59) ! 1205: */ ! 1206: #define EMUTABLE 0x43 ! 1207: #define NOEMULATE .long noemulate ! 1208: #define EMULATE(a) .long _EM/**/a ! 1209: .globl _emJUMPtable ! 1210: _emJUMPtable: ! 1211: /* f8 */ EMULATE(ashp); EMULATE(cvtlp); NOEMULATE; NOEMULATE ! 1212: /* fc */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE ! 1213: /* 00 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE ! 1214: /* 04 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE ! 1215: /* 08 */ EMULATE(cvtps); EMULATE(cvtsp); NOEMULATE; EMULATE(crc) ! 1216: /* 0c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE ! 1217: /* 10 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE ! 1218: /* 14 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE ! 1219: /* 18 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE ! 1220: /* 1c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE ! 1221: /* 20 */ EMULATE(addp4); EMULATE(addp6); EMULATE(subp4); EMULATE(subp6) ! 1222: /* 24 */ EMULATE(cvtpt); EMULATE(mulp); EMULATE(cvttp); EMULATE(divp) ! 1223: /* 28 */ NOEMULATE; EMULATE(cmpc3); EMULATE(scanc); EMULATE(spanc) ! 1224: /* 2c */ NOEMULATE; EMULATE(cmpc5); EMULATE(movtc); EMULATE(movtuc) ! 1225: /* 30 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE ! 1226: /* 34 */ EMULATE(movp); EMULATE(cmpp3); EMULATE(cvtpl); EMULATE(cmpp4) ! 1227: /* 38 */ EMULATE(editpc); EMULATE(matchc); EMULATE(locc); EMULATE(skpc) ! 1228: ! 1229: /* ! 1230: * The following is called with the stack set up as follows: ! 1231: * ! 1232: * (sp): Opcode ! 1233: * 4(sp): Instruction PC ! 1234: * 8(sp): Operand 1 ! 1235: * 12(sp): Operand 2 ! 1236: * 16(sp): Operand 3 ! 1237: * 20(sp): Operand 4 ! 1238: * 24(sp): Operand 5 ! 1239: * 28(sp): Operand 6 ! 1240: * 32(sp): Operand 7 (unused) ! 1241: * 36(sp): Operand 8 (unused) ! 1242: * 40(sp): Return PC ! 1243: * 44(sp): Return PSL ! 1244: * 48(sp): TOS before instruction ! 1245: * ! 1246: * Each individual routine is called with the stack set up as follows: ! 1247: * ! 1248: * (sp): Return address of trap handler ! 1249: * 4(sp): Opcode (will get return PSL) ! 1250: * 8(sp): Instruction PC ! 1251: * 12(sp): Operand 1 ! 1252: * 16(sp): Operand 2 ! 1253: * 20(sp): Operand 3 ! 1254: * 24(sp): Operand 4 ! 1255: * 28(sp): Operand 5 ! 1256: * 32(sp): Operand 6 ! 1257: * 36(sp): saved register 11 ! 1258: * 40(sp): saved register 10 ! 1259: * 44(sp): Return PC ! 1260: * 48(sp): Return PSL ! 1261: * 52(sp): TOS before instruction ! 1262: */ ! 1263: ! 1264: SCBVEC(emulate): ! 1265: movl r11,32(sp) # save register r11 in unused operand ! 1266: movl r10,36(sp) # save register r10 in unused operand ! 1267: cvtbl (sp),r10 # get opcode ! 1268: addl2 $8,r10 # shift negative opcodes ! 1269: subl3 r10,$EMUTABLE,r11 # forget it if opcode is out of range ! 1270: bcs noemulate ! 1271: movl _emJUMPtable[r10],r10 # call appropriate emulation routine ! 1272: jsb (r10) # routines put return values into regs 0-5 ! 1273: movl 32(sp),r11 # restore register r11 ! 1274: movl 36(sp),r10 # restore register r10 ! 1275: insv (sp),$0,$4,44(sp) # and condition codes in Opcode spot ! 1276: addl2 $40,sp # adjust stack for return ! 1277: rei ! 1278: noemulate: ! 1279: addl2 $48,sp # adjust stack for ! 1280: .word 0xffff # "reserved instruction fault" ! 1281: SCBVEC(emulateFPD): ! 1282: .word 0xffff # "reserved instruction fault" ! 1283: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.