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