title fptrap -- 7/32 unix floating-point emulator entry fptrap extrn uisa0,lra * * The following equates are used to generate single and/or double * precision versions. * Note that the same flags must also be defined in param.h * SPFPT equ 1 if 1, simulate single-precision f.p. DPFPT equ 1 if 1, simulate double-precision f.p. LRAI equ 0 if 1, lra instruction available SIGBUS equ 10 SIGFPT equ 8 SIGINS equ 4 r0 equ 0 r1 equ 1 r2 equ 2 r3 equ 3 r4 equ 4 r5 equ 5 r6 equ 6 sp equ 7 e8 equ 8 e9 equ 9 ea equ 10 eb equ 11 ec equ 12 ed equ 13 ee equ 14 ef equ 15 e9.x equ 9 ec.s equ 12 ee.stat equ 14 ef.loc equ 15 * register usage: r0,r1,r2,r6 scratch * r3 address of users saved r8 ( see reg.h ) * r4 address of users fp regs in ppda * r5 real pc in kernal segment * ed (rd) real destination addr * * * stack data area definition * data struc handlr ds adc gregs ds 8*adc ends title entry sequence *--------------pre-processor fptrap equ * shi sp,data allocate local variables on stack stm e8,gregs(sp) save r8-r15 just like c lis r0,SIGINS set to return error if not fp opcode * on first instruction stb r0,laflag look ahead flag l r3,data(sp) addr of users saved r0 ( see reg.h ) * lm ee.stat,9*adc(r3) old psw shi r3,10*adc adjust to point to users saved r8 * so all offsets are +ve l r4,data+4(sp) pointer to users fp regs * fptrap1 equ * look ahead entry ( see nofault ) lr r1,ef.loc make pc real wrt kernal seg regs la r2,uisa0 mac registers ifnz LRAI lra r1,0(r2) else bal r6,lra load real addr endc * btc x'd',sigbuse if pc not valid ( not present or * not executable ) lr r5,r1 save real pc * *--------------the simulated instruction interpretation lb e8,0(r5) opcode lb ed,1(r5) r1 & r2 field lr ec.s,ed r1 into source register srls ec.s,2 r1*4 ais ef.loc,2 update location counter ais r5,2 update real pc lb e8,opcodes(e8) pointer to vector tables l e9,vectab1(e8) 1st level handler pointer l e8,vectab2(e8) second level handler pointer sta e8,handlr(sp) br e9 go to 1st level handler title format preprocessors *--------------register & register instructions ifnz SPFPT xer equ * srls ec.s,1 force r1 to multiple-of-4 boundary nhi ec.s,x'1c' ar ec.s,r4 address of pseudo register ar ed,ed r2*2 nhi ed,x'1c' force r2 to multiple-of-4 boundary ar ed,r4 address of pseudo-register go.to.it l eb,handlr(sp) br eb go to 2nd level handler endc ifnz DPFPT xdr equ * nhi ec.s,x'38' force r1 to multiple-of-8 boundary slls ed,2 r2*4 nhi ed,x'38' force r2 to multiple-of-8 boundary ai ec.s,32(r4) make up the register's physical addr ai ed,32(r4) l eb,handlr(sp) br eb go to second levle handler endc *--------------register & memory instruction ifnz SPFPT xes equ * lis r0,1 if store type instruction b xe1 * xe equ * lis r0,0 set load type instruction xe1 sth r0,lsflag srls ec.s,1 force r1 to multiple-of-4 boundary nhi ec.s,x'1c' ar ec.s,r4 address of pseudo - register endc ifnz DPFPT b xd.2 xds equ * enter here if store type instruction lis r0,1 set flag b xd1 xd equ * lis r0,0 set load type instruction xd1 sth r0,lsflag nhi ec.s,x'38' force r1 to multiple-of-8 boundary ai ec.s,32(r4) endc xd.2 equ * lhl e9,0(r5) get 1st address h/w thi e9,x'8000' bnz rx2 rx2 format thi e9,x'4000' bz rx1 rx1 format *--------------rx3 ais ef.loc,2 update location counter ais r5,2 update real pc as well exhr eb,e9 address to bits 0-15 of eb lhl ea,0(r5) get 2nd address h/w or eb,ea merge address parts ni eb,y'ffffff' retain 24 bit address nhi ed,x'f' test 1st index register bz rx3nondx no index rx3.2 lb ed,grtab(ed) offset from users saved r8 a eb,0(r3,ed) users saved rx lr ed,e9 srls ed,8 rx2 to bits 28-31 of ed lr e9,eb partially completed address *--------------rx1, rx2 indexing enter here rx1 la e8,rx3.5 prepare exit address nhi ed,x'f' do indexing bz noindex no 2nd indexing for rx3 rx1.1 equ * * rx3.4 lb ed,grtab(ed) offset from users saved r8 a e9,0(r3,ed) users saved rx * no-indexing rx1 & rx2 join here noindex lr r1,e9 destination addr la r2,uisa0 mac regs ifnz LRAI lra r1,0(r2) else bal r6,lra load real address endc btc x'c',sigbuse send illegal adddress msg to user bfc x'2',noindx1 if not write protected lh r0,lsflag bz noindx1 if load type instuction b sigbuse else illegal address noindx1 lr ed,r1 real address returned form lra br e8 goto rx3.5 or fldr or flr.2 rx3.5 ais ef.loc,2 update location counter ais r5,2 update real pc as well ni ed,y'fffffffc' force onto a full-word boundary * ed contains destination addr in program space l e8,handlr(sp) br e8 go to 2nd level handler *--------------rx2 rx2 sll e9,17 get the relative address sra e9,17 with an appropriate sign ai e9,2(ef.loc) adjust it within physical space b rx1 *--------------no indexing for rx3 * rx3nondx lr r1,eb make destination addr real la r2,uisa0 mac regs ifnz LRAI lra r1,0(r2) else bal r6,lra make addr real endc btc x'c',sigbuse address is illegal bfc x'2',rx3no1 if not write protected lh r0,lsflag bz rx3no1 if load type instruction b sigbuse else bus error rx3no1 lr ed,r1 real address 2 b rx3.5 *--------------termination logic dpfinal equ * ti ee.stat,4 did overflow occur ? bz nofault nope ti ee.stat,x'1000' is af interrupt enabled ? bz nofault oh no * sigfpte equ * li r0,SIGFPT indicate arith error to trap.c b creturn * * * exit here if illegal address was encountered * sigbuse equ * * li r0,SIGBUS indicate bus error to trap.c b creturn * * exit here if non-floating point opcode * flt.iih equ * crash equ * sis ef.loc,2 set pc back to the instruction lb r0,laflag return code b creturn *--------------happy end errfree equ * nofault equ * lis r0,0 stb r0,laflag set return code for subsequent non-fp * opcodes b fptrap1 look ahead at next instruction. * * common exit point * creturn equ * stm ee.stat,19*adc(r3) store revised psw back * into users saved regs lm e8,gregs(sp) restore callers regs ahi sp,data remove temporaries from stack br ef exit back to trap.c title ste and ce ifnz SPFPT *-----------------------------store floating ste l ea,0(ec.s) move reg st ea,0(ed) to memory b nofault else ok *-----------------------------compare floating ce equ * ni ee.stat,-16 clear current condition code l ea,0(ec.s) get source l eb,0(ed) and destn bnm ce.2 b if dest 0+ lr ea,ea both minus? bm ce.1 b if so *-----------------------------plus always greater than minus stps ais ee.stat,2 set g flag b dpfinal get out *-----------------------------both minus ce.1 sr eb,ea generate b-a bm stms b if a> b bp stps b if b>a b dpfinal exit if equal *-----------------------------dest plus ce.2 lr ea,ea test source bnm ce.3 branch if both plus *-----------------------------minus always less than plus stms ais ee.stat,9 b dpfinal get out *-----------------------------both plus ce.3 sr ea,eb generate a-b bm stms b if a>b bp stps b if b>a b dpfinal exit if equal title le *-----------------------------load floating le equ * ni ee.stat,-16 clear current cc l ea,0(ed) get datum to be loaded ti ea,y'f00000' normalized already? bz le.2 branch if no lr ea,ea test sign bm stm store with proper status b stp *-----------------------------number needs to be normalized le.2 ti ea,y'ffffff' test for zero bz stz lr e9.x,ea exponent to x le.4 slls ea,4 adjust left 1 digit si e9,y'1000000' decrement exponent btc 12,underflo b if underflow le.4a ti ea,y'f00000' normalized yet? bz le.4 b if no le.5 xr ea,e9.x merge exponent and a ni ea,y'ffffff' xr ea,e9.x le.6 bm stm store a with appropriate status bp stp b sta *-----------------------------store a with minus status stm ais ee.stat,1 set l flag b sta go store a *-----------------------------store a with plus status stp ais ee.stat,2 set g flag *-----------------------------just plain store a sta st ea,0(ec.s) store a b dpfinal get out *-----------------------------underflow underflo ais ee.stat,4 set v flag *-----------------------------store zero stz xr ea,ea clear a b sta go store a title me *-----------------------------multiply floating me equ * ni ee.stat,-16 clear current cc l ea,0(ec.s) fetch a bz sta exit if zero l eb,0(ed) load b bz stz exit if zero lr e9.x,ea exponent to x ni ea,y'ffffff' xr e9.x,ea zero x's fraction field ar e9.x,eb add exponents bc me.c go to me.2 if c=v bno me.2 b me.1 me.c bo me.2 *-----------------------------carry out of exponent field me.1 ti e9.x,y'40000000' test for overflow bnz overflo b me.3 *-----------------------------no carry out of exponent field me.2 ti e9.x,y'40000000' test for underflow bz underflo me.3 si e9.x,y'40000000' restore excess-64 notation ni eb,y'ffffff' clear b's expoment slls eb,7 adjust a and b for best precision slls ea,7 lr ed,ea xr ea,ea mr ea,ed ti ea,y'3c000000' test result magnitude bz me.4 b if only 2-place shift reqd ahi ea,32 me.3a srls ea,6 shift right by 6 b le.5 merge exp and store result *-----------------------------only shift by 2, result is small me.4 ais ea,2 round ti ea,y'3c000000' did rounding cause another digit? bnz me.3a b if yes si e9.x,y'1000000' else adjust exponent btc 12,underflo srls ea,2 normalize b le.5 merge exp and store result title stme and lme *-----------------------------store multiple floating stme equ * stmeloop equ * l ea,0(ec.s) move reg st ea,0(ed) store in user's address space * ais ed,4 ais ec.s,4 bump reg counter cli ec.s,32(r4) dont forget that r4 has pointer to users fp r bl stmeloop b nofault *-----------------------------load multiple floating lme equ * lmeloop equ * l ea,0(ed) move memory st ea,0(ec.s) to register ais ed,4 ais ec.s,4 done? clhi ec.s,32(r4) bl lmeloop b nofault title de *-----------------------------divide by zero div.by.0 ais ee.stat,12 set c and v flags l ea,0(ec.s) b sta *-----------------------------divide floating de equ * ni ee.stat,-16 clear cc l eb,0(ed) get divisor ti eb,y'00ffffff' bz div.by.0 out if divisor=0 l ea,0(ec.s) now get dividend bz sta out if dividend=0 lr e9.x,ea prepare to subtract exponents oi e9.x,y'ffffff' eliminate any chance of borrow sr e9.x,eb a exponent minus b exponent bc de.c go to de.2 if c=v bno de.2 b de.1 else de.1 de.c bo de.2 *-----------------------------borrow out of exponent field de.1 ti e9.x,y'40000000' check for underflow bz underflo b de.3 go adjust exponent *-----------------------------no borrow out of exponent field de.2 ti e9.x,y'40000000' test for overflow bnz overflo2 de.3 ai e9.x,y'40000000' restore excess-64 notation li ed,y'ffffff' put b magnitude in divisor reg ti eb,y'00f00000' operand should be normalized bz dpfinal nr ed,eb slls ed,6 xr eb,eb prepare for divide ni ea,y'ffffff' get rid of a exponent dr ea,ed divide. lr ea,eb ti ea,y'3c000000' test top digit bnz de.4 branch unless zero ais ea,2 round ti ea,y'3c000000' did rounding cause carry? bnz de.4a b if yes srls ea,2 normalize (2 bits) b le.5 go store result *-----------------------------large quotient de.4 ahi eb,32 round de.4a srls ea,6 normalize (6 bits) b aese.2b go test for overflow title ae and se *-----------------------------add floating ae equ * l eb,0(ed) pick up b b aese enter common process *-----------------------------subtract floating se equ * l eb,0(ed) pick up b xi eb,y'80000000' reverse sign *-----------------------------add and subtract common process aese l ea,0(ec.s) pick up a ni ee.stat,-16 clear cc exhr e9.x,ea exponents to work registers exhr ed,eb nhi e9.x,x'7f00' strip off signs nhi ed,x'7f00' sr e9.x,ed a exp minus b exp bz aese.3 b if equal bm aese.4 b if b > a clhi e9.x,x'600' a>>b? bnl aese.sta srls e9.x,6 lr ed,eb save b exp ni eb,y'ffffff' strip b's exponent srl eb,0(e9.x) adjust b lr e9.x,ea save a exp ni ea,y'ffffff' strip a's exponent *-----------------------------a > b agb xr ed,e9.x effective add or subtract? bnm aese.2 b if add sr ea,eb subtract bz sta if zero, go store it b le.4a else go normalize *-----------------------------a >> b aese.sta lr ea,ea b le.6 *-----------------------------effective add aese.2a lr e9.x,ed (b>a enters here) aese.2 ar ea,eb add ti ea,y'f000000' carry? bz le.5 if no, go store srl ea,4 normalize aese.2b ai e9.x,y'1000000' bump exponent bfc 12,le.5 go store if no overflow *-----------------------------overflow overflo xi e9.x,y'80000000' restore valid sign *-----------------------------overflow entry if sign is ok overflo2 li ea,y'7fffffff' largest possible number ais ee.stat,4 set v bit or ea,e9.x merge sign with number b le.6 go store with proper status *-----------------------------equal exponents aese.3 lr e9.x,ea save exponents lr ed,eb ni ea,y'ffffff' isolate magnitudes ni eb,y'ffffff' clr ea,eb if a=b pretend a>b bnl agb b bga *-----------------------------b exp > a exp aese.4 clhi e9.x,-x'500' b>>a? bnl aese.5 b if no lr ea,eb else go store b b le.6 *-----------------------------a must be adjusted aese.5 ar e9.x,ed complement exponent difference sr ed,e9.x srls ed,6 lr e9.x,ea save a exp ni ea,y'ffffff' strip exponent from a srl ea,0(ed) adjust a lr ed,eb save b exp ni eb,y'ffffff' strip b exponent *-----------------------------b > a bga xr e9.x,ed effective add or subtract? bnm aese.2a b if effective add sr eb,ea subtract bz stz if zero, go store it lr ea,eb else put reault in "a" registers lr e9.x,ed b le.4a and go normalize title fxr *-----------------------------fix (convert to integer) fxr nhi ee.stat,-16 zero current cc ar ed,ed r2 is floating reg nhi ed,x'1c' force it even ar ed,r4 address of pseudo reg l ea,0(ed) get floating number lr eb,ea magnitude to b slls eb,8 left justified lb e9.x,0(ed) exponent to x (low byte) ni e9.x,x'7f' dump sign si e9.x,x'40' is there an integer part? bnp fxrzero b if no lis ed,8 compare exponent with 8 sr ed,e9.x bm fxrovf exit if number too big bnz fxr.1 go adjust number unless exp=8 lr eb,eb exp=8 but it could still be too big bnm fxr.2 b if it is ok fxrovf ais ee.stat,4 set v flag li eb,y'7fffffff' set number as big as possible lr ea,ea bp fxrstore b fxr.2a fxr.1 slls ed,2 prepare to adjust srl eb,0(ed) adjust fxr.2 lr ea,ea test sign bp fxrstore fxr.2a xi eb,-1 ais eb,1 b fxrstore fxrzero xr eb,eb zero b fxrstore lr eb,eb test sign of number bz fxr.6 b if zero bm fxr.5 b if minus ais ee.stat,2 set g flag b fxr.6 fxr.5 ais ee.stat,1 set l flag fxr.6 equ * * srls ec.s,2 was r1 * 4 lb r1,grtab(ec.s) offset from users saved r8 st eb,0(r3,r1) put into users saved general reg * b nofault title flr *-----------------------------flr preprocessing flr.1 srls ec.s,1 source reg nhi ec.s,x'1c' word boundary ar ec.s,r4 address of pseudo reg * nhi ed,x'f' lb ed,grtab(ed) offset from users saved r8 l ed,0(r3,ed) general register * * note: in this case only, ed contains the value of the second * operand, not its address!! * *-----------------------------float (convert to real) flr.2 nhi ee.stat,-16 lr ea,ed get number to float bz sta out if zero bm flr.3 b if minus li e9.x,y'46000000' get starter exponent b flr.4 flr.3 li e9.x,y'c6000000' negative number xi ea,-1 ai ea,1 flr.4 ti ea,y'ff000000' normalized to 6 digits? bz le.4a <= 6 digits, go finish normalization ai e9.x,y'1000000' > 6 digits, shift right srls ea,4 and fix exponent b flr.4 try again * since everything is done at this point, fxr.10 (see the * instruction modification routines section) returns directly * to nofault. endc title load and store double-precision floating ifnz DPFPT *--------------load double-precision floating ld equ * nhi ee.stat,-16 clear current condition code l e9,4(ed) l e8,0(ed) ti e8,y'f00000' is it normalized? bz normlize ld.50 lr e8,e8 bm stmd datum is -ve *--------------positive number - flag g stpd ais ee.stat,2 set g flag st e9,4(ec.s) st e8,0(ec.s) b dpfinal *--------------negative number - flag l stmd ais ee.stat,1 set l flag *--------------zero or exception stad st e9,4(ec.s) st e8,0(ec.s) b dpfinal *--------------forced zero stzd xr e9,e9 xr e8,e8 b stad *--------------store double-precision floating std equ * l e9,4(ec.s) no condition code changes l e8,0(ec.s) st e8,0(ed) st e9,4(ed) b errfree title load multiple and store multiple double-precision float *--------------load multiple double-precision floating lmd equ * *--------------lmd loop lmd.10 l e8,0(ed) move memory l e9,4(ed) st e8,0(ec.s) to double-precision floating reg st e9,4(ec.s) ais ed,8 ais ec.s,8 cli ec.s,64+32(r4) finished? r4 = fwa of sp fp regs bl lmd.10 not quite b errfree *--------------store multiple double-precision floating stmd.00 equ * *--------------stmd loop stmd.10 l e8,0(ec.s) move double-precision floating reg l e9,4(ec.s) st e8,0(ed) to memory st e9,4(ed) ais ec.s,8 ais ed,8 cli ec.s,64+32(r4) done? bl stmd.10 not yet b errfree title overflow and underflow *--------------overflow overfld li e8,y'7fffffff' largest possible no li e9,y'ffffffff' ais ee.stat,4 set v flag or e8,ed get an appropriate sign bm stmd -ve b stpd +ve *--------------underflow underfld ais ee.stat,4 set v flag xr e8,e8 zeroise the number xr e9,e9 b stad title normalization *--------------normalization of double-precision floating normlize equ * ti e8,y'ffffff' test if a1=zero bz norm.10 lhi ed,-1 lr ea,e8 get exponent ni e8,y'ffffff' separate fraction xr ea,e8 separate sign & exponent norm.05 si ea,y'1000000' decrement exponent btc 12,underfld c or v set - underflow slls e8,4 a1 rll e9,4 a2 slls ed,4 mask ti e8,y'f00000' bz norm.05 needs more ... lr eb,e9 save a2 nr e9,ed result2 xr eb,e9 separate most significant of old a2 or e8,eb fraction a1 ar e8,ea attach sign and exponent bm stmd -ve b stpd +ve not zero *--------------a1 fraction zero norm.10 lr e9,e9 a2 ? 0 bz stzd forced x'0000000000000000' si e8,y'6000000' cater for 6 x digits from a1 btc 12,underfld c or v set - underflow rrl e9,8 norm.15 ti e9,y'f00000' potentially normalized? bnz norm.20 yes, branch si e8,y'1000000' decrement exponent btc 12,underfld c or v set - underflow rll e9,4 b norm.15 norm.20 lr ea,e9 normalization's terminated ni e9,y'ff000000' a2 xr ea,e9 most significant of old a2 ar e8,ea a1 bm stmd -ve b stpd +ve not zero title compare double-precision floating *--------------compare double-precision floating cd equ * nhi ee.stat,-16 clear current condition code l ea,0(ed) b1 bnm cd.10 b is +ve l e8,0(ec.s) a1 bm cd.30 a -ve, b -ve cd.5 ais ee.stat,2 a > b , set flag g b dpfinal * cd.10 l e8,0(ec.s) a1 bnm cd.20 a is +ve cd.15 ais ee.stat,9 a < b , set flags l & c b dpfinal * cd.20 clr e8,ea a ? b , both identical signs bc cd.15 a < b btc 3,cd.5 a > b l e9,4(ec.s) a2, a1 = b1 cl e9,4(ed) a2 ? b2 bc cd.15 a2 < b2, a < b btc 3,cd.5 a > b b dpfinal cd.30 clr e8,ea a -ve, b -ve bc cd.5 b<a btc 3,cd.15 b>a l e9,4(ec.s) cl e9,4(ed) bc cd.5 b2<a2 btc 3,cd.15 b>a b dpfinal title add and subtract double-precision floating *--------------add double-precision floating ad equ * nhi ee.stat,-16 clear current condition code l eb,4(ed) b2 l ea,0(ed) b1 b adsd.00 *--------------subtract double-precision floating sd equ * nhi ee.stat,-16 clear current condition code l eb,4(ed) b2 l ea,0(ed) b1 xi ea,y'80000000' reverse sign *--------------add and subtract common sequence adsd.00 l e9,4(ec.s) a2 l e8,0(ec.s) a1 st ec.s,source exhr ec,e8 a's exponent exhr ed,ea b's exponent nhi ec,x'7f00' value of a's exponent nhi ed,x'7f00' value of b's exponent sr ec,ed bz adsd.60 exponents are equal bm adsd.70 a<b (magnitudes) clhi ec,x'e00' a>b (magnitudes) bnl adsd.55 a>>b (magnitudes) *--------------a > b adsd.03 srls ec,6 st ea,expb b's exponent shi ec,24 test if shifted more or less than 6x bnm adsd.40 shift 6 or more hex digits ni ea,y'ffffff' b1 ahi ec,24 srl eb,0(ec) rrl ea,0(ec) lhi ed,-1 construct a mask srl ed,0(ec) lr ec,ea nr ea,ed adjusted b1 xr ec,ea t'least signif dig of original b1 or eb,ec new b2 adsd.05 lr ec,e8 preserve a's exponent ni e8,y'ffffff' xr ec,e8 clear a1 fraction adsd.12 st ec,exp preserve result's exponent x ec,expb effective + or - bnm adsd.25 effective add *--------------effective subtraction l ec.s,source restore source address sr e9,eb a2-b2=r2 bnc adsd.15 sis e8,1 a1-1:=a1 adsd.15 sr e8,ea a1-b1=r1 bz adsd.20 r1=0 adsd.17 o e8,exp merge result and exponent ti e8,y'f00000' bz normlize normalize the result b ld.50 store the result adsd.20 lr e9,e9 bz stad result is zero b adsd.17 *--------------effective addition adsd.25 l ec.s,source restore source address ar e9,eb a2+b2=r2 bnc adsd.30 ais e8,1 a1+1:=a1 adsd.30 ar e8,ea a1+b1=r1 bz stzd result is zero l ed,exp ti e8,y'f000000' bnz adsd.35 or e8,ed no change in exponent 's value bm stmd b stpd adsd.35 ai ed,y'1000000' increase exponent's value btc 12,adsd.85 overflow srls e9,4 rrl e8,4 lr eb,e8 ni e8,y'ffffff' result1 (r1) xr eb,e8 the least significant digit of r1 or e9,eb result2 (r2) or e8,ed add exponent bm stmd b stpd *--------------a>b, continued 1 adsd.40 srl eb,24 6 or more hex digits difference slls ea,8 b1 or eb,ea new b2 xr ea,ea zero to b1 lr ec,ec bz adsd.05 no more adjustments to b1 srl eb,0(ec) new adjusted b b adsd.05 *--------------a >> b adsd.55 l ec.s,source lr e8,e8 bm stmd b stpd *--------------a's exp = b's exp adsd.60 st ea,expb preserve b1 lr ec,e8 a's sign and exponent ni ea,y'ffffff' b1 - strip off sign & exponent ni e8,y'ffffff' a1 xr ec,e8 result's exponent clr e8,ea a compared to b bc adsd.65 a < b btc 3,adsd.12 a > b clr e9,eb bnc adsd.12 a > or = b adsd.65 lr ea,e8 a1 to b1 l e8,expb b1 to a1 lr ed,e9 a2 to save lr e9,eb b2 to a2 lr eb,ed a2 to b2 st ec,expb a's exponent becomes b's lr ec,e8 new a's exponent ni e8,y'ffffff' strip off the new exponent xr ec,e8 b adsd.12 *--------------a < b adsd.70 clhi ec,-x'd00' bl adsd.80 a<<b xhi ec,-1 ais ec,1 lr ed,e8 exchange a and b lr e8,ea lr ea,ed lr ed,e9 lr e9,eb lr eb,ed b adsd.03 *--------------a << b adsd.80 l ec.s,source lr e9,eb lr e8,ea bm stmd b stpd * adsd.85 si ed,y'1000000' overflow b overfld title multiply double-precision floating *--------------multiply double-precision floating md equ * nhi ee.stat,-16 clear current condition code l e9,4(ec.s) a2 l e8,0(ec.s) a1 bz stzd if zero exit l eb,4(ed) b2 l ea,0(ed) b1 bz stzd if zero exit lr ed,e8 ni ed,y'ff000000' zero to a1 fraction ar ed,ea a-exp + b-exponent bc md.04 if c=v go to md.08 bno md.08 b md.06 md.04 bo md.08 *--------------carry out of exponent field md.06 ti ed,y'40000000' test for overflow bz md.10 si ed,y'1000000' test if potentially o.k. ti ed,y'40000000' bnz md.75 no, overflow ni ea,y'ffffff' potential overflow xr ed,ea retain excess-128 notation and ais ed,1 set potential overflow flag b md.12 *--------------no carry out of exponent field md.08 ti ed,y'40000000' must be gt or eq 64 bz underfld underflow, < 64 md.10 ni ea,y'ffffff' clear b's exponent xr ed,ea retain result of exp. manipulation md.12 si ed,y'40000000' restore excess-64 notation ni e8,y'ffffff' clear a's exponent stm ec.s,source save: ec...source address * ed...exponent with potential * overflow flag on/off * ee,ef...the instruction's psw * multiply both a and b by 16 in order * to utilize the most significant * digits of a2 and b2 slls e8,4 a1 slls ea,4 b1 rll e9,4 a2 rll eb,4 b2 lr ec,e9 lr ed,eb nhi ec,x'f' retain f7 of a nhi ed,x'f' retain f7 of b ar e8,ec seven x digits in a1 ar ea,ed 7 x digits in b1 xr e9,ec clear extra digit in a2 & b2 xr eb,ed lr ed,e9 a2 bm md.50 bit 0 set lr ef,eb b2 bm md.50 bit 0 set *--------------all four pseudo operands are positive numbers mr ec,eb a2*b2 = c mr ee,e8 b2*a1 = d lr ed,ec forget the irrelevant c2 lr ec,ee d1 ar ed,ef c1+d2 := d2 bnc md.15 ais ec,1 md.15 lr ef,e9 a2 mr ee,ea a2*b1 = e ar ec,ee d1+e1 := d1, no carry possible ar ed,ef d2+e2 := d2 bnc md.20 ais ec,1 md.20 lr ef,e8 a1 mr ee,ea a1*b1 = f ar ef,ec d1+f2 = r2 bnc md.30 f1 = r1 ais ee,1 f1+1 = r1 *-------------result constructed in e8 & e9 md.30 l e8,exp restore exponent ti ee,y'f00000' 1-st x digit bz md.40 not normalized thi e8,1 test potential overflow flag bnz md.70 overflow ar e8,ee lr e9,ef * restore saved values md.35 lm ee.stat,status l ec.s,source b ld.50 test if -ve or +ve *--------------normalize the result of multiplication md.40 thi e8,1 test the potential overflow flag bz md.42 no overflow detected earlier sis e8,1 no test for underflow, * no further exponent adjustment, * just clear the flag b md.43 md.42 si e8,y'1000000' result is to be normalizedp btc 12,md.45 underflow md.43 slls ee,4 r1*16 := r1 ar e8,ee r1+exponent rll ef,4 r2*16 := r2 lr e9,ef r2 nhi ef,x'f' retain the most sign digit of r2 xr e9,ef clear rubbish ar e8,ef most sign digit of r2 times 16 rll ed,4 bring in another hex digit lr ef,ed nhi ef,x'f' or e9,ef * restore saved values b md.35 md.45 lm ee.stat,status underflow due to normalization l ec.s,source b underfld *--------------adjusted a2 or b2 is negative md.50 srls e9,4 a2/16 srls eb,4 b2/16 lr ed,e9 a2 mr ec,eb a2*b2 = c slls ec,4 c1*16 := c1 rll ed,4 nhi ed,x'f' get the most sign.digit times 16 ar ed,ec forget the rest lr ef,eb b2 mr ee,e8 b2*a1 = d lr ec,ee d1 ar ed,ef c1+d2 := d2 bnc md.55 ais ec,1 md.55 lr ef,e9 a2 mr ee,ea a2*b1 = e ar ec,ee e1+d1 := d1, no chance of carry ar ed,ef e2+d2 := d2 bnc md.60 ais ec,1 md.60 slls ec,4 d1*16 rll ed,4 d2*16 lr eb,ed bring in another hex digit nhi eb,x'f' or ec,eb lr ef,e8 a1 mr ee,ea a1*b1 = e ar ef,ec e2+d1 = r2 bnc md.30 r1 ais ee,1 r1+1 := r1 b md.30 md.70 lm ee.stat,status overflow l ec.s,source lr ed,e8 get the sign source b overfld * md.75 xr e8,ea make up the sign lr ed,e8 b overfld title divide double-precision floating *--------------divide double-precision floating dd equ * nhi ee.stat,-16 clear current condition code l ea,0(ed) divisor b1 bz dd.70 divide by zero requested l eb,4(ed) b2 l e9,4(ec.s) a2 l e8,0(ec.s) a1 bz stzd result is zero lr ed,e8 get exponent oi ed,y'ffffff' eliminate any chance of borrow sr ed,ea subtract exponents bc dd.04 bno dd.08 b dd.06 dd.04 bo dd.08 *--------------borrow out of exponent field dd.06 ti ed,y'40000000' check for underflow bnz dd.10 ai ed,y'1000000' test if potentially o.k. ti ed,y'40000000' bz underfld definitely underflow ni ed,y'ff000000' pure exponent in ed ais ed,1 set potential underflow flag b dd.12 *--------------no borrow out of exponent field dd.08 ti ed,y'40000000' test for overflow bnz dd.75 yes, overflow dd.10 ni ed,y'ff000000' dd.12 ai ed,y'40000000' resultant exponent * with the potential underflow * flag set or reset ni e8,y'ffffff' clear a's exponent ni ea,y'ffffff' clear b's exponent stm ec.s,source save: ec...source address * ed...exponent with potential * underflow flag on/off * ee,ef...the instruction's psw xr ee,ee zero to result1 xr ef,ef zero to result2 li ec,y'1000000' * divide by repeated subtraction. * hexadecimal digits are basic * sources for decision-making and * the arithmetics clr e8,ea a1 ? b1 bc dd.30 a1 < b1 btc 3,dd.20 a1 > b1 clr e9,eb a2 ? b2 bc dd.30 a2 < b2 btc 3,dd.20 a2 > b2 lr ee,ec a=b, result's obvious b dd.40 *--------------a>b dd.20 sr e9,eb current a2-b2 = c2 bnc dd.22 sis e8,1 a1-1 := a1, no chance of borrow dd.22 sr e8,ea current a1-b1 = c1 ar ef,ec clr e8,ea a1 ? b1 bc dd.30 a1<b1 btc 3,dd.20 a1>b1 clr e9,eb a2?b2 bnc dd.20 a2> or = b2 *--------------a<b dd.30 srls ec,4 divide the adder by 16 btc 3,dd.35 there is a value in the adder lr ee,ee end of cycle, adder = 0 bnz dd.40 end of 2nd cycle lr ee,ef xr ef,ef li ec,y'10000000' *--------------next hexadecimal digit dd.35 slls e8,4 a1*16 rll e9,4 a2*16 lr ed,e9 get the most signif digit of a2 ni e9,y'fffffff0' xr ed,e9 separate current f7 of a2 ar e8,ed clr e8,ea a1 ? b1 bc dd.30 a1<b1 btc 3,dd.20 a1>b1 clr e9,eb a2?b2 bnc dd.20 a2 > or = b2 b dd.30 *--------------result build-up dd.40 l e8,exp ti ee,y'f000000' does it need normalization ? bnz dd.45 yes thi e8,1 test the potential underflow flag bnz dd.80 underflow b dd.50 and off we go... dd.45 rrl ee,4 normalize, r1/16 srls ef,4 r2/16 lr ed,ee separate the least signif digit of r ni ee,y'ffffff' xr ed,ee ar ef,ed thi e8,1 test the potential underflow flag bz dd.55 not set - increase exponent's value sis e8,1 reset the flag dd.50 or e8,ee everything's o.k. lr e9,ef lm ee.stat,status l ec.s,source lr e8,e8 bm stmd b stpd dd.55 ai e8,y'1000000' increase the exponent value bfc 12,dd.50 it is not an overflow * overflow dd.60 lm ee.stat,status l ec.s,source l ed,exp b overfld * division by zero dd.70 ais ee.stat,12 c and v flags b dpfinal dd.75 xr e8,ea lr ed,e8 b overfld * underflow dd.80 lm ee.stat,status l ec.s,source b underfld title float register - double-precision *--------------fldr pre-process fldr.00 equ * nhi ed,x'f' r2 is general register lb ed,grtab(ed) offset from user's saved r8 l ed,0(r3,ed) contents of general register * * note: in this case ed is the contents not address of r2 * nhi ec.s,x'38' r1 is float register ai ec.s,32(r4) address of double fp reg r1 *--------------float register - double precision (convert to real) fldr equ * nhi ee.stat,-16 clear current condition code lr ea,ed get the number to float bz stzd bm fldr.20 -ve li e8,y'48000000' starter exponent *--------------+ve and -ve common process fldr.10 rrl ea,8 lr e9,ea two least significant x digits ni e9,y'ff000000' result2 xr ea,e9 6 most significant x digits or e8,ea result1 ti e8,y'f00000' needs normalization? bz normlize lr e8,e8 bm stmd b stpd *--------------negative integer fldr.20 xhi ea,-1 complement the bit pattern ais ea,1 complement the -ve number li e8,y'c8000000' starter exponent - negative mantissa b fldr.10 title fix register - double-precision *--------------fix register double-precision (convert to integer) fxdr equ * nhi ee.stat,-16 clear current condition code slls ed,2 multiply by 4 to get floating reg nhi ed,x'38' force it on & bytes boundary ai ed,32(r4) add fwa of double precision regs l e8,0(ed) a1 l e9,4(ed) a2 exhr ea,e8 nhi ea,x'7f00' separate exponent shi ea,x'4000' is there an integer part? bnp fxdr.30 no srls ea,8 pure exponent sis ea,8 bp fxdr.25 number is too big xhi ea,-1 complement the bit pattern ais ea,1 complement the number ti e8,y'800000' is the number potentially too big? bnz fxdr.20 yes *--------------final conversion to integer fxdr.05 srl e9,24 move two least significant x digits lr eb,e8 slls eb,8 adjust 6 most signif x digits or eb,e9 construct number's magnitude lr ea,ea examine effective exponent bz fxdr.07 no adjustment required slls ea,2 multiply by 4 to get no of bits srl eb,0(ea) result's magnitude fxdr.07 lr e8,e8 bp fxdr.15 +ve result fxdr.08 equ * xhi eb,-1 complement the bit pattern ais eb,1 complement the number fxdr.10 ais ee.stat,1 -ve result, set l flag b fxdr.6 fxdr.15 ais ee.stat,2 +ve result, set g flag fxdr.17 b fxdr.6 go store result in general reg. *--------------exceptional values for conversion fxdr.20 lr ea,ea test pseudo exponent bnz fxdr.05 it will fit in a user register *--------------number is too big fxdr.25 ais ee.stat,4 set v flag li eb,y'7fffffff' value as big as possible lr e8,e8 bm fxdr.08 b fxdr.15 +ve result *--------------number too small or zero fxdr.30 xr eb,eb zeroise fxdr.6 equ * * srls ec.s,2 was r1 * 4 lb r1,grtab(ec.s) offset from users saved r8 st eb,0(r3,r1) put into users saved general reg * b nofault endc title vector tables vectab1 dac flt.iih illegals all have a code of 0 ifnz SPFPT single-precision dac xer,xer,xer,xer,xer,xer rr floating dac y'80000000'+fxr fxr dac y'80000000'+flr.1 flr dac xes rx floating (store) dac xe,xe,xe,xe,xe,xe rx floating dac y'80000000'+xes stme dac y'80000000'+xe lme endc ifz SPFPT do 17 dac flt.iih endc lv equ *-vectab1 ifnz DPFPT double-precision dac xdr,xdr,xdr,xdr,xdr,xdr rr floating dac y'80000000'+fxdr fxdr dac y'80000000'+fldr.00 fldr dac xds rx floating (store) dac xd,xd,xd,xd,xd,xd rx floating dac y'80000000'+xds stmd dac y'80000000'+xd lmd endc ifz DPFPT do 17 dac flt.iih endc *--------------second level vector table vectab2 dac flt.iih shouldn't ever get here ifnz SPFPT single-precision dac le,ce,ae,se,me,de rr floating dac flt.iih fxr dac flr.2 flr dac y'80000000'+ste ste dac le,ce,ae,se,me,de rx floating dac y'80000000'+stme stme dac lme lme endc ifz SPFPT do 17 dac crash endc ifnz DPFPT double-precision dac ld,cd,ad,sd,md,dd rr floating dac flt.iih fxdr dac fldr fldr dac y'80000000'+std std dac ld,cd,ad,sd,md,dd rx floating dac y'80000000'+stmd.00 stmd dac lmd lmd endc ifz DPFPT do 17 dac crash endc title operation code table *--------------opcode table align 4 opcodes do 5 db 0,0,0,0,0,0,0,0 ifnz SPFPT single-precision db 4,8,12,16,20,24,28,32 else db 0,0,0,0,0,0,0,0 endc db 0,0,0,0,0,0,0,0 ifnz DPFPT double-precision db lv,lv+4,lv+8,lv+12,lv+16,lv+20,lv+24,lv+28 else db 0,0,0,0,0,0,0,0 endc do 4 db 0,0,0,0,0,0,0,0 ifnz SPFPT single-precision db 36,0,0,0,0,0,0,0,40,44,48,52,56,60,0,0 else do 2 db 0,0,0,0,0,0,0,0 endc ifnz DPFPT double-precision db lv+32 else db 0 endc ifnz SPFPT single-precision db 64,68 else db 0,0 endc db 0,0,0,0,0 ifnz DPFPT double-precision db lv+36,lv+40,lv+44,lv+48,lv+52,lv+56,lv+60,lv+64 else db 0,0,0,0,0,0,0,0 endc do 16 db 0,0,0,0,0,0,0,0 title constants and work areas *--------------work areas * used by: ad,sd *--------------work areas * * offsets from users saved r8 of users * general registers. * see reg.h for additional info * we cant use reg.h exactly because offsets * must be +ve * grtab equ * db 10*adc r0 db 11*adc r1 db 12*adc r2 db 13*adc r3 db 14*adc r4 db 15*adc r5 db 16*adc r6 db 17*adc r7 - sp db 0*adc r8 db 1*adc r9 db 2*adc r10 db 3*adc r11 db 4*adc r12 db 5*adc r13 db 6*adc r14 db 18*adc r15 lsflag dc h'0' load/store type instruction laflag db 0 look ahead flag * align 4 source das 1 save area for source address * used by: ad,sd,md,dd exp das 1 save area for result's exponent * used by: ad,sd,md,dd status das 2 save area for the user's psw * used by: md,dd ***************the order of source, exp & status should not be changed expb das 1 auxiliary area for b's exponent * used by: ad,sd end