1: /* 2: * LICENSED FROM DIGITAL EQUIPMENT CORPORATION 3: * COPYRIGHT (c) 4: * DIGITAL EQUIPMENT CORPORATION 5: * MAYNARD, MASSACHUSETTS 6: * 1985, 1986, 1987 7: * ALL RIGHTS RESERVED 8: * 9: * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT 10: * NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL 11: * EQUIPMENT CORPORATION. DIGITAL MAKES NO REPRESENTATIONS ABOUT 12: * THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS 13: * SUPPLIED "AS IS" WITHOUT EXPRESSED OR IMPLIED WARRANTY. 14: * 15: * IF THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR ITS LICENSEES 16: * MODIFY THE SOFTWARE IN A MANNER CREATING DERIVATIVE COPYRIGHT 17: * RIGHTS, APPROPRIATE COPYRIGHT LEGENDS MAY BE PLACED ON THE 18: * DERIVATIVE WORK IN ADDITION TO THAT SET FORTH ABOVE. 19: * 20: * @(#)mch_fpsim.s 1.2 (2.11BSD GTE) 12/26/92 21: */ 22: #include "DEFS.h" 23: 24: /* 25: * Kernel floating point simulator 26: */ 27: 28: #if defined(FPSIM) || defined(GENERIC) 29: 30: m.ext = 200 / long mode bit 31: m.lngi = 100 / long integer mode 32: 33: _u = 140000 / XXX 34: uar0 = _u + U_AR0 / u.u_ar0 35: fec = _u + U_FPERR + F_FEC / u.u_fperr.f_fec 36: fea = _u + U_FPERR + F_FEA / u.u_fperr.f_fea 37: fpsr = _u + U_FPSR / u.u_fps.u.fpsr 38: ac0 = _u + U_FPREGS + [0.*8.] / u.u_fsp.u_fpregs[0] 39: ac1 = _u + U_FPREGS + [1.*8.] / u.u_fsp.u_fpregs[1] 40: ac2 = _u + U_FPREGS + [2.*8.] / u.u_fsp.u_fpregs[2] 41: ac3 = _u + U_FPREGS + [3.*8.] / u.u_fsp.u_fpregs[3] 42: 43: /* 44: * fptrap() 45: * 46: * Return Status: 47: * 0 successful simulation 48: * otherwise the signal number. 49: */ 50: ENTRY(fptrap) 51: jsr r5,csv 52: sub $74,sp 53: instr = -12 / int instr; 54: trapins = -14 / int trapins; 55: pctmp = -24 / double pctmp; 56: modctl2 = -26 / int (*modctl2)(); 57: modctl = -30 / int (*modctl)(); 58: local = -32 / int local; 59: bexp = -34 / int bexp; 60: breg = -44 / double breg; 61: bsign = -46 / int bsign; 62: aexp = -50 / int aexp; 63: areg = -60 / double areg; 64: asign = -62 / int asign; 65: sps = -64 / int sps; 66: spc = -66 / int spc; 67: ssp = -70 / int ssp; 68: / sr5 = -72 / int sr5; 69: / sr4 = -74 / int sr5; 70: / sr3 = -76 / int sr5; 71: / sr2 = -100 / int sr5; 72: sr1 = -102 / int sr1; 73: sr0 = -104 / int sr0; 74: 75: / make copies of all the registers - see trap.c (regloc) for the offsets 76: mov $sr0,r1 77: add r5,r1 78: mov $_regloc,r3 / see trap.c 79: mov $9.,r4 / r0,1,2,3,4,5,sp,pc,psw 80: 1: 81: movb (r3)+,r2 / fetch next register offset from u_ar0 82: asl r2 / make word index 83: add uar0,r2 / add in u_ar0 84: mov (r2),(r1)+ / save register 85: sob r4,1b 86: 87: / get the offending instruction 88: mov spc(r5),r1 89: dec r1 90: dec r1 91: jsr pc,ffuiword 92: mov r0,instr(r5) 93: 94: again: 95: sub $8,sp / room for double push /hmm.... 96: clr local(r5) 97: mov instr(r5),r4 98: bic $7777,r4 99: cmp r4,$170000 100: beq 1f 101: jmp badins 102: 1: 103: / clear fp error 104: bic $100000,fpsr 105: bic $170000,instr(r5) 106: mov instr(r5),r4 107: bit $7000,r4 108: bne class3 109: bit $700,r4 110: bne class2 111: cmp r4,$12 112: blos 1f 113: jmp badins 114: 1: 115: asl r4 116: jmp *agndat(r4) 117: 118: class2: 119: cmp instr(r5),$400 120: bge 1f 121: mov $mod0rx,modctl(r5) 122: mov $mod242,modctl2(r5) 123: br 2f 124: 1: 125: mov $mod0f,modctl(r5) 126: mov $mod24f,modctl2(r5) 127: 2: 128: jsr pc,fsrc /## jsr r1,fsrc 129: mov r3,instr(r5) 130: asl r4 / r4 = (r4&0700)>>7; 131: asl r4 132: clrb r4 133: swab r4 134: asl r4 135: jsr pc,*cls2dat(r4) 136: jmp sret 137: 138: 139: class3: 140: cmp instr(r5),$5000 141: blt 1f 142: mov instr(r5),r2 143: clrb r2 144: cmp r2,$6400 145: blt 2f 146: sub $1400,r2 147: 2: 148: cmp r2,$5000 149: bne 2f 150: mov $mod0rx,modctl(r5) 151: mov $mod242,modctl2(r5) 152: br 3f 153: 2: 154: cmp r2,$5400 155: bne 2f 156: mov $mod0ra,modctl(r5) 157: mov $mod24i,modctl2(r5) 158: br 3f 159: 2: 160: mov $mod0f,modctl(r5) 161: mov $mod24d,modctl2(r5) 162: br 3f 163: 1: 164: mov $mod0f,modctl(r5) 165: mov $mod24f,modctl2(r5) 166: 3: 167: jsr pc,fsrc /### jsr r1,fsrc 168: jsr pc,freg 169: mov r2,instr(r5) 170: bis $2,local(r5) / mark as local, since (r2) is always local 171: clrb r4 / r4 = r4 & ~0377 >> 8; 172: swab r4 173: asl r4 174: jsr pc,*cls3dat(r4) 175: br sret 176: 177: 178: i.cfcc: 179: mov fpsr,r1 / get the FPP reg 180: bic $!17,r1 / clear everything except the NZVC bits 181: bic $17,sps(r5) / clear the old NZVC bits 182: bis r1,sps(r5) / set the new NZVC bits 183: br ret 184: 185: i.setf: 186: bic $m.ext,fpsr 187: br ret 188: 189: i.setd: 190: bis $m.ext,fpsr 191: br ret 192: 193: i.seti: 194: bic $m.lngi,fpsr 195: br ret 196: 197: i.setl: 198: bis $m.lngi,fpsr 199: br ret 200: 201: sret: 202: mov $fpsr,r2 203: bic $17,(r2) 204: bit $2,local(r5) 205: bne 1f 206: mov instr(r5),r1 207: jsr pc,ffuword 208: br 2f 209: 1: 210: mov *instr(r5),r0 211: 2: 212: swab r0 213: tstb r0 214: bpl 1f 215: bis $10,(r2) 216: br ret 217: 1: 218: bne ret 219: bis $4,(r2) 220: 221: ret: 222: / restore all the new register values 223: mov $sr0,r1; add r5,r1 224: mov $_regloc,r3 225: mov $9.,r4 226: 1: 227: movb (r3)+,r2 228: asl r2 229: add uar0,r0 230: mov (r1)+,(r0) 231: sob r4,1b 232: 233: bit $020,sps(r5) / Check to see if T bit was set. 234: bne 1f 235: mov spc(r5),r1 / Check the next instruction 236: jsr pc,ffuiword / to see if it is another 237: cmp r0,$170000 / floating point instruction. 238: blo 3f 239: mov r0,instr(r5) 240: add $2,spc(r5) / Update our copy of pc, 241: mov uar0,r0 / update 242: add $2,2.(r0) / the real pc, 243: jbr again / and save the trap. 244: 3: 245: clr r0 / Normal Return 246: 2: 247: jmp cret 248: 1: 249: mov $SIGTRAP.,r0 250: br 2b 251: badins: / Illegal Instruction 252: mov $SIGILL.,r0 253: br 2b 254: segfault: / Segmentation Violation 255: mov uar0,r0 / Don't update any registers, but 256: sub $2,2.(r0) / back up the pc to point to the instruction. 257: mov $SIGSEGV.,r0 258: br 2b 259: fpexcept: / Floating Point Exception 260: / restore all the new register values, and then 261: / return an error. 262: mov $sr0,r1; add r5,r1 263: mov uar0,r0 264: mov (r1)+,(r0) / r0 265: mov (r1)+,-4.(r0) / r1 266: mov (r1)+,-20.(r0) / r2 267: mov (r1)+,-18.(r0) / r3 268: mov (r1)+,-16.(r0) / r4 269: mov (r1)+,-12.(r0) / r5 270: mov (r1)+,-6.(r0) / sp (r6) 271: mov (r1)+,2.(r0) / pc (r7) 272: mov (r1)+,4.(r0) / psw 273: mov $SIGFPE.,r0 274: jmp cret 275: 276: freg: 277: mov instr(r5),r2 278: bic $!300,r2 279: asr r2 280: asr r2 281: asr r2 282: add $ac0,r2 283: rts pc 284: 285: fsrc: 286: mov instr(r5),r3 287: bic $!7,r3 / register 288: asl r3 289: add $sr0,r3; add r5,r3 290: mov instr(r5),r0 291: bic $!70,r0 / mode 292: asr r0 293: asr r0 294: jmp *moddat(r0) 295: 296: 297: mod24f: 298: mov $4,r0 299: bit $m.ext,fpsr 300: beq 1f 301: add $4,r0 302: 1: 303: rts pc 304: 305: mod24d: 306: mov $8,r0 307: bit $m.ext,fpsr 308: beq 1f 309: sub $4,r0 310: 1: 311: rts pc 312: 313: mod242: 314: mov $2,r0 315: rts pc 316: 317: mod24i: 318: mov $2,r0 319: bit $m.lngi,fpsr 320: beq 1f 321: add $2,r0 322: 1: 323: rts pc 324: 325: mod0: 326: jmp *modctl(r5) 327: 328: mod0f: 329: sub $sr0,r3 330: sub r5,r3 331: cmp r3,$6*2 332: bhis badi1 333: asl r3 334: asl r3 335: add $ac0,r3 336: br mod0rx 337: 338: mod0ra: 339: bit $m.lngi,fpsr 340: bne badi1 341: 342: mod0r: 343: mov $ssp,-(sp); add r5,(sp) 344: cmp r3,(sp)+ 345: bhis badi1 346: mod0rx: 347: bis $3,local(r5) / mark it as a local addr, not a user addr 348: rts pc /### rts r1 349: 350: mod1: / register deferred *rn or (rn) 351: mov $spc,-(sp); add r5,(sp) 352: cmp r3,(sp)+ 353: beq badi1 354: mov (r3),r3 355: br check 356: 357: mod2: 358: mov (r3),-(sp) 359: jsr pc,*modctl2(r5) 360: mov $spc,-(sp); add r5,(sp) 361: cmp r3,(sp)+ 362: bne 1f 363: mov (r3),r1 / PC relative - immediate $n 364: jsr pc,ffuiword 365: mov r0,pctmp(r5) 366: mov $pctmp,(sp); add r5,(sp) 367: / need to clean garbage out of rest of pctmp(r5) 368: mov (sp),r0 369: tst (r0)+ 370: clr (r0)+ 371: clr (r0)+ 372: clr (r0)+ 373: mov $2,r0 374: bis $3,local(r5) / signify address is not in user space 375: 376: 1: / Auto increment (rn)+ 377: add r0,(r3) 378: mov (sp)+,r3 379: br check 380: 381: mod3: 382: mov (r3),r1 383: mov $spc,-(sp); add r5,(sp) 384: cmp r3,(sp)+ 385: bne 1f 386: jsr pc,ffuiword / PC Absolute *$A 387: br 2f 388: 1: 389: jsr pc,ffuword /autoincrement deferred *(rn)+ 390: 2: 391: add $2,(r3) 392: mov r0,r3 393: br check 394: 395: mod4: / Autodecrement -(rn) 396: mov $spc,-(sp); add r5,(sp) 397: cmp r3,(sp)+ / test pc 398: beq badi1 399: jsr pc,*modctl2(r5) 400: sub r0,(r3) 401: mov (r3),r3 402: br check 403: 404: mod5: / Autodecrement Deferred *-(rn) 405: mov $spc,-(sp); add r5,(sp) 406: cmp r3,(sp)+ 407: beq badi1 408: sub $2,(r3) 409: mov (r3),r1 410: jsr pc,ffuword 411: mov r0,r3 412: br check 413: 414: mod6: / Index or PC relative 415: mov spc(r5),r1 416: jsr pc,ffuiword 417: add $2,spc(r5) 418: add (r3),r0 419: mov r0,r3 420: br check 421: 422: mod7: / Index Deferred or PC Relative Deferred 423: jsr pc,mod6 /### jsr r1,mod6 424: mov r3,r1 425: jsr pc,ffuword 426: mov r0,r3 427: br check 428: 429: badi1: 430: jmp badins 431: 432: check: 433: bit $1,r3 434: bne 1f 435: rts pc /### rts r1 436: 1: 437: jmp segfault 438: 439: setab: 440: bis $4,local(r5) 441: mov $asign,r0; add r5,r0 442: jsr pc,seta 443: mov r3,r2 444: bit $1,local(r5) 445: bne 1f 446: bic $4,local(r5) 447: 1: 448: mov $bsign,r0; add r5,r0 449: 450: seta: 451: clr (r0) 452: bit $4,local(r5) 453: bne 4f 454: mov r0,-(sp) 455: mov r2,r1; jsr pc,ffuword; mov r0,r1 456: add $2,r2 457: mov (sp)+,r0 458: br 5f 459: 4: 460: mov (r2)+,r1 461: 5: 462: mov r1,-(sp) 463: beq 1f 464: blt 2f 465: inc (r0)+ 466: br 3f 467: 2: 468: dec (r0)+ 469: 3: 470: bic $!177,r1 471: bis $200,r1 472: br 2f 473: 1: 474: clr (r0)+ 475: 2: 476: mov r1,(r0)+ 477: bit $4,local(r5) 478: bne 4f 479: mov r1,-(sp) 480: mov r3,-(sp) 481: mov r0,r3 482: mov r2,r1 483: jsr pc,ffuword; add $2,r1; mov r0,(r3)+ 484: bit $m.ext,fpsr 485: beq 5f 486: jsr pc,ffuword; add $2,r1; mov r0,(r3)+ 487: jsr pc,ffuword; add $2,r1; mov r0,(r3)+ 488: br 6f 489: 5: 490: clr (r3)+ 491: clr (r3)+ 492: 6: 493: mov r1,r2 494: mov r3,r0 495: mov (sp)+,r3 496: mov (sp)+,r1 497: br 3f 498: 4: 499: mov (r2)+,(r0)+ 500: bit $m.ext,fpsr 501: beq 2f 502: mov (r2)+,(r0)+ 503: mov (r2)+,(r0)+ 504: br 3f 505: 2: 506: clr (r0)+ 507: clr (r0)+ 508: 3: 509: mov (sp)+,r1 510: asl r1 511: clrb r1 512: swab r1 513: sub $200,r1 514: mov r1,(r0)+ / exp 515: rts pc 516: 517: norm: 518: mov $areg,r0; add r5,r0 519: mov (r0)+,r1 520: mov r1,-(sp) 521: mov (r0)+,r2 522: bis r2,(sp) 523: mov (r0)+,r3 524: bis r3,(sp) 525: mov (r0)+,r4 526: bis r4,(sp)+ 527: bne 1f 528: clr asign(r5) 529: rts pc 530: 1: 531: bit $!377,r1 532: beq 1f 533: clc 534: ror r1 535: ror r2 536: ror r3 537: ror r4 538: inc (r0) 539: br 1b 540: 1: 541: bit $200,r1 542: bne 1f 543: asl r4 544: rol r3 545: rol r2 546: rol r1 547: dec (r0) 548: br 1b 549: 1: 550: mov r4,-(r0) 551: mov r3,-(r0) 552: mov r2,-(r0) 553: mov r1,-(r0) 554: rts pc 555: 556: .globl _grow, nofault 557: PS = 177776 558: 559: ffuword: 560: mov $1f,trapins(r5) 561: mov PS,-(sp) 562: SPLHIGH 563: mov nofault,-(sp) 564: mov $ferr1,nofault 565: 1: 566: mfpd (r1) 567: mov (sp)+,r0 568: br 2f 569: 570: ffuiword: 571: mov PS,-(sp) 572: SPLHIGH 573: mov nofault,-(sp) 574: mov $ferr2,nofault /stack isn't in I space, so just bomb out. 575: mfpi (r1) 576: mov (sp)+,r0 577: br 2f 578: 579: fsuword: 580: mov $1f,trapins(r5) 581: mov PS,-(sp) 582: SPLHIGH 583: mov nofault,-(sp) 584: mov $ferr1,nofault 585: 1: 586: mov r0,-(sp) 587: mtpd (r1) 588: 2: 589: mov (sp)+,nofault 590: mov (sp)+,PS 591: rts pc 592: 593: ferr1: 594: /first fault could be because we need to grow the stack. 595: mov (sp)+,nofault 596: mov (sp)+,PS 597: mov r0,-(sp) /save r0 and r1 because 598: mov r1,-(sp) /grow() will muck them up 599: mov ssp(r5),-(sp) 600: jsr pc,_grow 601: tst (sp)+ 602: tst r0 603: bne 1f 604: jmp segfault 605: 1: 606: mov (sp)+,r1 /restore r1 607: mov (sp)+,r0 /and r0 608: mov PS,-(sp) 609: SPLHIGH 610: mov nofault,-(sp) 611: mov $ferr2,nofault 612: jmp *trapins(r5) 613: 614: ferr2: 615: /second fault, we have a valid memory fault now, 616: /so make the users program bomb out! 617: mov (sp)+,nofault 618: mov (sp)+,PS 619: jmp segfault 620: 621: 622: / class 2 instructions 623: 624: fiuv = 04000 625: 626: i.ldfps: 627: bit $1,local(r5) 628: beq 1f 629: mov (r3),fpsr 630: br 2f 631: 1: 632: mov r3,r1 633: jsr pc,ffuword 634: mov r0,fpsr 635: 2: 636: jmp ret 637: 638: i.stfps: 639: bit $1,local(r5) 640: beq 1f 641: mov fpsr,(r3) 642: br 2f 643: 1: 644: mov fpsr,r0 645: mov r3,r1 646: jsr pc,fsuword 647: 2: 648: jmp ret 649: 650: i.stst: 651: bit $1,local(r5) 652: beq 1f 653: / must be either a register or immediate mode, only save fec 654: mov fec,(r3)+ 655: br 2f 656: 1: 657: mov fec,r0 658: mov r3,r1 659: jsr pc,fsuword 660: mov fea,r0 661: add $2,r1 662: jsr pc,fsuword 663: 2: 664: jmp ret 665: 666: i.clrx: 667: bit $1,local(r5) 668: bne 1f 669: clr r0 670: mov r3,r1 671: jsr pc,fsuword 672: add $2,r1 673: jsr pc,fsuword 674: bit $m.ext,fpsr 675: beq 2f 676: add $2,r1 677: jsr pc,fsuword 678: add $2,r1 679: jsr pc,fsuword 680: 2: 681: rts pc 682: 1: 683: clr (r3)+ 684: clr (r3)+ 685: bit $m.ext,fpsr 686: beq 2f 687: clr (r3)+ 688: clr (r3)+ 689: 2: 690: rts pc 691: 692: i.tstx: 693: bit $fiuv,fpsr 694: bne 2f 695: 1: 696: rts pc 697: /this could be real easy, except that the lousy tstx instruction 698: / does the fiuv trap AFTER execution, not before. So, since 699: / normally this instruction doesn't get done until after the rts pc, 700: / we explicitly do it here. 701: 2: 702: bit $2,local(r5) 703: bne 1b 704: mov $fpsr,r2 705: bic $17,(r2) 706: mov instr(r5),r1 707: jsr pc,ffuword 708: swab r0 709: tstb r0 710: bpl 1f 711: bis $10,(r2) /set negative flag 712: br 2f 713: 1: 714: bne 2f 715: bis $4,(r2) /set zero flag 716: 2: 717: jsr pc,chkuv /finally, check for sign bit and a biased 0 exp 718: jmp ret 719: 720: i.absx: 721: bit $1,local(r5) 722: beq 1f 723: bic $!77777,(r3) 724: rts pc 725: 1: 726: mov r3,r1 727: jsr pc,ffuword 728: bit $fiuv,fpsr 729: beq 2f 730: jsr pc,chkuv 731: 2: 732: bic $!77777,r0 733: mov r3,r1 734: jsr pc,fsuword 735: rts pc 736: 737: chkuv: 738: mov r0,-(sp) 739: bic $77,(sp) /clear the fraction part 740: bit $140000,(sp)+ /check for sign bit and biased exponent of 0 741: bne 1f 742: jmp undefvar 743: 1: 744: rts pc 745: 746: undefvar: 747: mov $12., fec 748: jmp fpexcept 749: 750: i.negx: 751: bit $1,local(r5) 752: bne 1f 753: 754: mov r3,r1 755: jsr pc,ffuword 756: bit $fiuv,fpsr 757: beq 2f 758: jsr pc,chkuv 759: 2: 760: tst r0 761: beq 2f 762: add $100000,r0 763: mov r3,r1 764: jsr pc,fsuword 765: 2: 766: rts pc 767: 1: 768: tst (r3) 769: beq 2f 770: add $100000,(r3) 771: 2: 772: rts pc 773: 774: / class 3 775: 776: i.ldx: 777: bit $1,local(r5) 778: bne 1f 779: /user to kernel 780: mov r3,r1; jsr pc,ffuword 781: bit $fiuv,fpsr 782: beq 2f 783: jsr pc,chkuv 784: 2: 785: mov r0,(r2)+ 786: add $2,r1; jsr pc,ffuword; mov r0,(r2)+ 787: bit $m.ext,fpsr 788: beq 2f 789: add $2,r1; jsr pc,ffuword; mov r0,(r2)+ 790: add $2,r1; jsr pc,ffuword; mov r0,(r2)+ 791: rts pc 792: 1: 793: /kernel to kernel 794: mov (r3)+,(r2)+ 795: mov (r3)+,(r2)+ 796: bit $m.ext,fpsr 797: beq 2f 798: mov (r3)+,(r2)+ 799: mov (r3)+,(r2)+ 800: rts pc 801: 2: 802: clr (r2)+ 803: clr (r2)+ 804: rts pc 805: 806: i.stx: 807: bit $1,local(r5) 808: bne 1f 809: /kernel to user 810: mov (r2)+,r0; mov r3,r1; jsr pc,fsuword; 811: mov (r2)+,r0; add $2,r1; jsr pc,fsuword 812: bit $m.ext,fpsr 813: beq 2f 814: mov (r2)+,r0; add $2,r1; jsr pc,fsuword 815: mov (r2)+,r0; add $2,r1; jsr pc,fsuword 816: br 2f 817: 1: 818: /kernel to kernel 819: mov (r2)+,(r3)+ 820: mov (r2)+,(r3)+ 821: bit $m.ext,fpsr 822: beq 2f 823: mov (r2)+,(r3)+ 824: mov (r2)+,(r3)+ 825: 2: 826: jmp ret / does not set cc's 827: 828: i.cmpx: 829: mov $areg,r4; add r5,r4 830: mov r4,instr(r5) / bit 2 of local(r5) is already set. 831: bit $1,local(r5) 832: bne 9f 833: mov r3,r1; jsr pc,ffuword 834: bit $fiuv,fpsr 835: beq 1f 836: jsr pc,chkuv 837: 1: 838: tst (r2) 839: bge 1f 840: tst r0 841: bge 1f 842: cmp (r2),r0 843: bgt 4f 844: blt 3f 845: 1: 846: cmp (r2)+,r0 847: bgt 3f 848: blt 4f 849: add $2,r1; jsr pc,ffuword; cmp (r2)+,r0 850: bne 5f 851: bit $m.ext,fpsr 852: beq 2f 853: add $2,r1; jsr pc,ffuword; cmp (r2)+,r0 854: bne 5f 855: add $2,r1; jsr pc,ffuword; cmp (r2)+,r0 856: beq 2f 857: br 5f 858: 859: 9: 860: tst (r2) 861: bge 1f 862: tst (r3) 863: bge 1f 864: cmp (r2),(r3) 865: bgt 4f 866: blt 3f 867: 1: 868: cmp (r2)+,(r3)+ 869: bgt 3f 870: blt 4f 871: cmp (r2)+,(r3)+ 872: bne 5f 873: bit $m.ext,fpsr 874: beq 2f 875: cmp (r2)+,(r3)+ 876: bne 5f 877: cmp (r2)+,(r3)+ 878: beq 2f 879: 5: 880: bhi 3f 881: 4: 882: movb $1,1(r4) 883: rts pc 884: 3: 885: mov $-1,(r4) 886: rts pc 887: 2: 888: clr (r4) 889: rts pc 890: 891: i.ldcyx: /ldcdf or ldcfd 892: bit $1,local(r5) 893: bne 1f 894: mov r3,r1; jsr pc,ffuword 895: bit $fiuv,fpsr 896: beq 2f 897: jsr pc,chkuv 898: 2: 899: mov r0,(r2)+ 900: add $2,r1; jsr pc,ffuword; mov r0,(r2)+ 901: bit $m.ext,fpsr 902: bne 2f 903: add $2,r1; jsr pc,ffuword; mov r0,(r2)+ 904: add $2,r1; jsr pc,ffuword; mov r0,(r2)+ 905: rts pc 906: 1: 907: mov (r3)+,(r2)+ 908: mov (r3)+,(r2)+ 909: bit $m.ext,fpsr 910: bne 2f 911: mov (r3)+,(r2)+ 912: mov (r3)+,(r2)+ 913: rts pc 914: 2: 915: clr (r2)+ 916: clr (r2)+ 917: rts pc 918: 919: i.stcxy: 920: bit $1,local(r5) 921: bne 1f 922: mov (r2)+,r0; mov r3,r1; jsr pc,fsuword 923: mov (r2)+,r0; add $2,r1; jsr pc,fsuword 924: bit $m.ext,fpsr 925: bne 2f 926: clr r0 927: add $2,r1; jsr pc,fsuword 928: add $2,r1; jsr pc,fsuword 929: br 2f 930: 1: 931: mov (r2)+,(r3)+ 932: mov (r2)+,(r3)+ 933: bit $m.ext,fpsr 934: bne 2f 935: clr (r3)+ 936: clr (r3)+ 937: 2: 938: rts pc 939: 940: i.ldcjx: 941: mov $asign,r2; add r5,r2 942: mov $1,(r2)+ 943: bit $1,local(r5) 944: bne 1f 945: mov r3,r1; jsr pc,ffuword 946: bit $fiuv,fpsr 947: beq 2f 948: jsr pc,chkuv 949: 2: 950: mov r0,(r2)+ 951: bit $m.lngi,fpsr 952: beq 3f 953: add $2,r1; jsr pc,ffuword; mov r0,(r2)+ 954: br 2f 955: 1: 956: mov (r3)+,(r2)+ 957: bit $m.lngi,fpsr 958: beq 3f 959: mov (r3)+,(r2)+ 960: 2: 961: clr (r2)+ 962: clr (r2)+ 963: mov $32.-8,(r2)+ 964: jmp saret 965: 3: 966: clr (r2)+ 967: clr (r2)+ 968: clr (r2)+ 969: mov $16.-8,(r2) 970: jmp saret 971: 972: i.stcxj: 973: mov r3,instr(r5) 974: bit $1,local(r5) 975: bne 1f /bit 2 of local(r5) is already set 976: bic $2,local(r5) 977: 1: 978: mov $asign,r0; add r5,r0 979: bis $4,local(r5) /tell seta that r2 is a local addr 980: jsr pc,seta 981: clr r4 982: mov $areg,r0; add r5,r0 983: mov (r0)+,r1 984: mov (r0)+,r2 985: mov (r0)+,r3 986: mov aexp(r5),r0 987: 1: 988: cmp r0,$48.-8 989: bge 1f 990: clc 991: ror r1 992: ror r2 993: ror r3 994: inc r0 995: br 1b 996: 1: 997: bgt 7f 998: tst r1 999: beq 1f 1000: 7: 1001: bis $1,r4 / C-bit 1002: 1: 1003: bit $m.lngi,fpsr 1004: beq 1f 1005: tst asign(r5) 1006: bge 2f 1007: neg r3 1008: adc r2 1009: bcs 2f 1010: neg r2 1011: bis $10,r4 / N-bit 1012: 2: 1013: bit $2,local(r5) 1014: bne 9f 1015: mov r4,-(sp) / save r4 1016: mov r1,-(sp) / save r1 1017: mov r0,-(sp) / save r0 1018: mov r2,r0; mov instr(r5),r1; jsr pc,fsuword 1019: mov r3,r0; add $2,r1; jsr pc,fsuword 1020: mov (sp)+,r0 / restore r0 1021: mov (sp)+,r1 / restore r1 1022: br t1 1023: 9: 1024: mov r4,-(sp) / save r4 1025: mov instr(r5),r4 1026: mov r2,(r4) 1027: mov r3,2(r4) 1028: t1: 1029: mov (sp)+,r4 / restore r4 1030: bis r2,r3 1031: br 8f 1032: 1: 1033: tst r2 1034: beq 1f 1035: bis $1,r4 / C-bit 1036: 1: 1037: tst asign(r5) 1038: bge 2f 1039: neg r3 1040: bis $10,r4 / N-bit 1041: 2: 1042: bit $1,local(r5) 1043: bne 9f 1044: mov r3,r0 1045: mov instr(r5),r1 1046: jsr pc,fsuword 1047: tst r3 1048: br 8f 1049: 9: 1050: mov r3,*instr(r5) 1051: 8: 1052: bne 1f 1053: bis $4,r4 / Z-bit 1054: 1: 1055: bic $17,sps(r5) 1056: bic $17,fpsr 1057: bis r4,sps(r5) 1058: bis r4,fpsr 1059: jmp ret 1060: 1061: xoflo: 1062: bis $1,fpsr / set fixed overflow (carry) 1063: jmp ret 1064: 1065: i.ldexp: 1066: mov $asign,r0; add r5,r0 1067: bis $4,local(r5) /tell seta that r2 is a local addr 1068: jsr pc,seta 1069: bit $1,local(r5) 1070: bne 1f 1071: mov r3,r1; jsr pc,ffuword; mov r0,aexp(r5) 1072: br 2f 1073: 1: 1074: mov (r3),aexp(r5) 1075: 2: 1076: jsr pc,reta 1077: jmp sret 1078: 1079: i.stexp: 1080: mov $asign,r0; add r5,r0 1081: bis $4,local(r5) /tell seta that r2 is a local addr 1082: jsr pc,seta 1083: bit $1,local(r5) 1084: bne 1f 1085: mov aexp(r5),r0; mov r3,r1; jsr pc,fsuword 1086: mov r3,instr(r5) 1087: bic $17,sps(r5) 1088: tst aexp(r5) 1089: br 3f 1090: 1: 1091: mov aexp(r5),(r3) 1092: mov r3,instr(r5) 1093: bic $17,sps(r5) 1094: tst (r3) 1095: 3: 1096: bmi 1f 1097: bne 2f 1098: bis $4,sps(r5) / Z-bit 1099: br 2f 1100: 1: 1101: bis $10,sps(r5) / N-bit 1102: 2: 1103: / next 4 lines because of previous mov r3,instr(r5) 1104: bit $1,local(r5) / bit 2 of local(r5) is currently set. 1105: bne 1f 1106: bic $2,local(r5) 1107: 1: 1108: jmp sret 1109: 1110: 1111: i.addx: 1112: jsr pc,setab 1113: br 1f 1114: 1115: i.subx: 1116: jsr pc,setab 1117: neg bsign(r5) 1118: 1: 1119: tst bsign(r5) 1120: beq reta 1121: tst asign(r5) 1122: beq retb 1123: mov aexp(r5),r1 1124: sub bexp(r5),r1 1125: blt 1f 1126: beq 2f 1127: cmp r1,$56. 1128: bge reta 1129: mov $breg,r0; add r5,r0 1130: br 4f 1131: 1: 1132: neg r1 1133: cmp r1,$56. 1134: bge retb 1135: mov $areg,r0; add r5,r0 1136: 4: 1137: mov r1,-(sp) 1138: mov (r0)+,r1 1139: mov (r0)+,r2 1140: mov (r0)+,r3 1141: mov (r0)+,r4 1142: add (sp),(r0) 1143: 1: 1144: clc 1145: ror r1 1146: ror r2 1147: ror r3 1148: ror r4 1149: dec (sp) 1150: bgt 1b 1151: mov r4,-(r0) 1152: mov r3,-(r0) 1153: mov r2,-(r0) 1154: mov r1,-(r0) 1155: tst (sp)+ 1156: 2: 1157: mov $aexp,r1; add r5,r1 1158: mov $bexp,r2; add r5,r2 1159: mov $4,r0 1160: cmp asign(r5),bsign(r5) 1161: bne 4f 1162: clc 1163: 1: 1164: adc -(r1) 1165: bcs 3f 1166: add -(r2),(r1) 1167: 2: 1168: dec r0 1169: bne 1b 1170: br 5f 1171: 3: 1172: add -(r2),(r1) 1173: sec 1174: br 2b 1175: br 5f 1176: 4: 1177: clc 1178: 1: 1179: sbc -(r1) 1180: bcs 3f 1181: sub -(r2),(r1) 1182: 2: 1183: dec r0 1184: bne 1b 1185: br 5f 1186: 3: 1187: sub -(r2),(r1) 1188: sec 1189: br 2b 1190: 1191: saret: 1192: mov $areg,r1; add r5,r1 1193: 5: 1194: tst (r1) 1195: bge 3f 1196: mov $areg+8,r1; add r5,r1 1197: mov $4,r0 1198: clc 1199: 1: 1200: adc -(r1) 1201: bcs 2f 1202: neg (r1) 1203: 2: 1204: dec r0 1205: bne 1b 1206: neg -(r1) 1207: 3: 1208: jsr pc,norm 1209: br reta 1210: 1211: retb: 1212: mov $bsign,r1; add r5,r1 1213: mov $asign,r2; add r5,r2 1214: mov $6,r0 1215: 1: 1216: mov (r1)+,(r2)+ 1217: dec r0 1218: bne 1b 1219: 1220: reta: 1221: mov instr(r5),r2 1222: mov $asign,r0; add r5,r0 1223: tst (r0) 1224: beq unflo 1225: mov aexp(r5),r1 1226: cmp r1,$177 1227: bgt ovflo 1228: cmp r1,$-177 1229: blt unflo 1230: add $200,r1 1231: swab r1 1232: clc 1233: ror r1 1234: tst (r0)+ 1235: bge 1f 1236: bis $100000,r1 1237: 1: 1238: bic $!177,(r0) 1239: bis (r0)+,r1 1240: bit $2,local(r5) 1241: bne 3f 1242: mov r3,-(sp) /save r3 1243: mov r0,r3 /and move r0 to r3 1244: mov r1,r0; mov r2,r1; jsr pc,fsuword 1245: mov (r3)+,r0; add $2,r1; jsr pc,fsuword 1246: bit $m.ext,fpsr 1247: beq 2f 1248: mov (r3)+,r0; add $2,r1; jsr pc,fsuword 1249: mov (r3)+,r0; add $2,r1; jsr pc,fsuword 1250: 2: 1251: mov r3,r0 /move r3 back to r0 1252: mov (sp)+,r3 /and restor r3 1253: rts pc 1254: 3: 1255: mov r1,(r2)+ 1256: mov (r0)+,(r2)+ 1257: bit $m.ext,fpsr 1258: beq 1f 1259: mov (r0)+,(r2)+ 1260: mov (r0)+,(r2)+ 1261: 1: 1262: rts pc 1263: 1264: unflo: 1265: bit $2,local(r5) 1266: bne 1f 1267: clr r0 1268: mov r2,r1; jsr pc,fsuword 1269: add $2,r1; jsr pc,fsuword 1270: bit $m.ext,fpsr 1271: beq 2f 1272: add $2,r1; jsr pc,fsuword 1273: add $2,r1; jsr pc,fsuword 1274: br 2f 1275: 1: 1276: clr (r2)+ 1277: clr (r2)+ 1278: bit $m.ext,fpsr 1279: beq 2f 1280: clr (r2)+ 1281: clr (r2)+ 1282: 2: 1283: rts pc 1284: 1285: ovflo: 1286: bis $2,fpsr / set v-bit (overflow) 1287: jmp ret 1288: 1289: i.mulx: 1290: jsr pc,i.mul 1291: jbr saret 1292: 1293: i.modx: 1294: jsr pc,i.mul 1295: jsr pc,norm 1296: mov $asign,r0; add r5,r0 1297: mov $bsign,r1; add r5,r1 1298: mov $6,r2 1299: 1: 1300: mov (r0)+,(r1)+ 1301: dec r2 1302: bne 1b 1303: clr r0 / count 1304: mov $200,r1 / bit 1305: clr r2 / reg offset 1306: 1: 1307: add r5,r2 1308: cmp r0,aexp(r5) 1309: bge 2f / in fraction 1310: bic r1,areg(r2) 1311: br 3f 1312: 2: 1313: bic r1,breg(r2) 1314: 3: 1315: sub r5,r2 1316: inc r0 1317: clc 1318: ror r1 1319: bne 1b 1320: mov $100000,r1 1321: add $2,r2 1322: cmp r2,$8 1323: blt 1b 1324: jsr pc,norm 1325: jsr pc,reta 1326: cmp instr(r5),$ac1 1327: beq 1f 1328: cmp instr(r5),$ac3 1329: beq 1f 1330: bit $200,breg(r5) 1331: bne 2f 1332: clr bsign(r5) 1333: 2: 1334: add $8,instr(r5) 1335: jsr pc,retb 1336: sub $8,instr(r5) 1337: 1: 1338: rts pc 1339: 1340: i.divx: 1341: jsr pc,setab 1342: tst bsign(r5) 1343: beq zerodiv 1344: sub bexp(r5),aexp(r5) 1345: jsr pc,xorsign 1346: mov instr(r5),-(sp) 1347: mov $areg,r0; add r5,r0 1348: mov (r0),r1 1349: clr (r0)+ 1350: mov (r0),r2 1351: clr (r0)+ 1352: mov (r0),r3 1353: clr (r0)+ 1354: mov (r0),r4 1355: clr (r0)+ 1356: mov $areg,instr(r5); add r5,instr(r5) 1357: mov $400,-(sp) 1358: 1: 1359: mov $breg,r0; add r5,r0 1360: cmp (r0)+,r1 1361: blt 2f 1362: bgt 3f 1363: cmp (r0)+,r2 1364: blo 2f 1365: bhi 3f 1366: cmp (r0)+,r3 1367: blo 2f 1368: bhi 3f 1369: cmp (r0)+,r4 1370: bhi 3f 1371: 2: 1372: mov $breg,r0; add r5,r0 1373: sub (r0)+,r1 1374: clr -(sp) 1375: sub (r0)+,r2 1376: adc (sp) 1377: clr -(sp) 1378: sub (r0)+,r3 1379: adc (sp) 1380: sub (r0)+,r4 1381: sbc r3 1382: adc (sp) 1383: sub (sp)+,r2 1384: adc (sp) 1385: sub (sp)+,r1 1386: bis (sp),*instr(r5) 1387: 3: 1388: asl r4 1389: rol r3 1390: rol r2 1391: rol r1 1392: clc 1393: ror (sp) 1394: bne 1b 1395: mov $100000,(sp) 1396: add $2,instr(r5) 1397: mov $aexp,-(sp); add r5,(sp) 1398: cmp instr(r5),(sp)+ 1399: blo 1b 1400: tst (sp)+ 1401: mov (sp)+,instr(r5) 1402: jmp saret 1403: 1404: zerodiv: 1405: mov $4,fec 1406: jmp fpexcept 1407: 1408: i.mul: 1409: jsr pc,setab 1410: add bexp(r5),aexp(r5) 1411: dec aexp(r5) 1412: jsr pc,xorsign 1413: mov instr(r5),-(sp) 1414: mov $breg+4,instr(r5); add r5,instr(r5) 1415: bit $m.ext,fpsr 1416: beq 1f 1417: add $4,instr(r5) 1418: 1: 1419: clr r0 1420: clr r1 1421: clr r2 1422: clr r3 1423: clr r4 1424: 1: 1425: asl r0 1426: bne 2f 1427: inc r0 1428: sub $2,instr(r5) 1429: 2: 1430: cmp r0,$400 1431: bne 2f 1432: mov $breg,-(sp); add r5,(sp) 1433: cmp instr(r5),(sp)+ 1434: bhi 2f 1435: mov $areg,r0; add r5,r0 1436: mov r1,(r0)+ 1437: mov r2,(r0)+ 1438: mov r3,(r0)+ 1439: mov r4,(r0)+ 1440: mov (sp)+,instr(r5) 1441: rts pc 1442: 2: 1443: clc 1444: ror r1 1445: ror r2 1446: ror r3 1447: ror r4 1448: bit r0,*instr(r5) 1449: beq 1b 1450: mov r0,-(sp) 1451: mov $areg,r0; add r5,r0 1452: add (r0)+,r1 1453: clr -(sp) 1454: add (r0)+,r2 1455: adc (sp) 1456: clr -(sp) 1457: add (r0)+,r3 1458: adc (sp) 1459: add (r0)+,r4 1460: adc r3 1461: adc (sp) 1462: add (sp)+,r2 1463: adc (sp) 1464: add (sp)+,r1 1465: mov (sp)+,r0 1466: br 1b 1467: 1468: xorsign: 1469: cmp asign(r5),bsign(r5) 1470: beq 1f 1471: mov $-1,asign(r5) 1472: rts pc 1473: 1: 1474: mov $1,asign(r5) 1475: rts pc 1476: 1477: 1478: .data 1479: agndat: 1480: i.cfcc / 170000 1481: i.setf / 170001 1482: i.seti / 170002 1483: badins 1484: badins 1485: badins 1486: badins 1487: badins 1488: badins 1489: i.setd / 170011 1490: i.setl / 170012 1491: cls2dat: 1492: badins / 1700xx 1493: i.ldfps / 1701xx 1494: i.stfps / 1702xx 1495: i.stst / 1703xx 1496: i.clrx / 1704xx 1497: i.tstx / 1705xx 1498: i.absx / 1706xx 1499: i.negx / 1707xx 1500: cls3dat: 1501: badins / 1700xx 1502: badins / 1704xx 1503: i.mulx / 1710xx 1504: i.modx / 1714xx 1505: i.addx / 1720xx 1506: i.ldx / 1724xx 1507: i.subx / 1730xx 1508: i.cmpx / 1734xx 1509: i.stx / 1740xx 1510: i.divx / 1744xx 1511: i.stexp / 1750xx 1512: i.stcxj / 1754xx 1513: i.stcxy / 1760xx 1514: i.ldexp / 1764xx 1515: i.ldcjx / 1770xx 1516: i.ldcyx / 1774xx 1517: moddat: 1518: mod0 1519: mod1 1520: mod2 1521: mod3 1522: mod4 1523: mod5 1524: mod6 1525: mod7 1526: 1527: #endif /* FPSIM || GENERIC */