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