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