srem_mod.sa revision 1.3
11.3Scgd* $NetBSD: srem_mod.sa,v 1.3 1994/10/26 07:49:58 cgd Exp $ 21.3Scgd 31.1Smycroft* MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 41.1Smycroft* M68000 Hi-Performance Microprocessor Division 51.1Smycroft* M68040 Software Package 61.1Smycroft* 71.1Smycroft* M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. 81.1Smycroft* All rights reserved. 91.1Smycroft* 101.1Smycroft* THE SOFTWARE is provided on an "AS IS" basis and without warranty. 111.1Smycroft* To the maximum extent permitted by applicable law, 121.1Smycroft* MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 131.1Smycroft* INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 141.1Smycroft* PARTICULAR PURPOSE and any warranty against infringement with 151.1Smycroft* regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 161.1Smycroft* and any accompanying written materials. 171.1Smycroft* 181.1Smycroft* To the maximum extent permitted by applicable law, 191.1Smycroft* IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 201.1Smycroft* (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS 211.1Smycroft* PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR 221.1Smycroft* OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE 231.1Smycroft* SOFTWARE. Motorola assumes no responsibility for the maintenance 241.1Smycroft* and support of the SOFTWARE. 251.1Smycroft* 261.1Smycroft* You are hereby granted a copyright license to use, modify, and 271.1Smycroft* distribute the SOFTWARE so long as this entire notice is retained 281.1Smycroft* without alteration in any modified and/or redistributed versions, 291.1Smycroft* and that such modified versions are clearly identified as such. 301.1Smycroft* No licenses are granted by implication, estoppel or otherwise 311.1Smycroft* under any patents or trademarks of Motorola, Inc. 321.1Smycroft 331.1Smycroft* 341.1Smycroft* srem_mod.sa 3.1 12/10/90 351.1Smycroft* 361.1Smycroft* The entry point sMOD computes the floating point MOD of the 371.1Smycroft* input values X and Y. The entry point sREM computes the floating 381.1Smycroft* point (IEEE) REM of the input values X and Y. 391.1Smycroft* 401.1Smycroft* INPUT 411.1Smycroft* ----- 421.1Smycroft* Double-extended value Y is pointed to by address in register 431.1Smycroft* A0. Double-extended value X is located in -12(A0). The values 441.1Smycroft* of X and Y are both nonzero and finite; although either or both 451.1Smycroft* of them can be denormalized. The special cases of zeros, NaNs, 461.1Smycroft* and infinities are handled elsewhere. 471.1Smycroft* 481.1Smycroft* OUTPUT 491.1Smycroft* ------ 501.1Smycroft* FREM(X,Y) or FMOD(X,Y), depending on entry point. 511.1Smycroft* 521.1Smycroft* ALGORITHM 531.1Smycroft* --------- 541.1Smycroft* 551.1Smycroft* Step 1. Save and strip signs of X and Y: signX := sign(X), 561.1Smycroft* signY := sign(Y), X := |X|, Y := |Y|, 571.1Smycroft* signQ := signX EOR signY. Record whether MOD or REM 581.1Smycroft* is requested. 591.1Smycroft* 601.1Smycroft* Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0. 611.1Smycroft* If (L < 0) then 621.1Smycroft* R := X, go to Step 4. 631.1Smycroft* else 641.1Smycroft* R := 2^(-L)X, j := L. 651.1Smycroft* endif 661.1Smycroft* 671.1Smycroft* Step 3. Perform MOD(X,Y) 681.1Smycroft* 3.1 If R = Y, go to Step 9. 691.1Smycroft* 3.2 If R > Y, then { R := R - Y, Q := Q + 1} 701.1Smycroft* 3.3 If j = 0, go to Step 4. 711.1Smycroft* 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to 721.1Smycroft* Step 3.1. 731.1Smycroft* 741.1Smycroft* Step 4. At this point, R = X - QY = MOD(X,Y). Set 751.1Smycroft* Last_Subtract := false (used in Step 7 below). If 761.1Smycroft* MOD is requested, go to Step 6. 771.1Smycroft* 781.1Smycroft* Step 5. R = MOD(X,Y), but REM(X,Y) is requested. 791.1Smycroft* 5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to 801.1Smycroft* Step 6. 811.1Smycroft* 5.2 If R > Y/2, then { set Last_Subtract := true, 821.1Smycroft* Q := Q + 1, Y := signY*Y }. Go to Step 6. 831.1Smycroft* 5.3 This is the tricky case of R = Y/2. If Q is odd, 841.1Smycroft* then { Q := Q + 1, signX := -signX }. 851.1Smycroft* 861.1Smycroft* Step 6. R := signX*R. 871.1Smycroft* 881.1Smycroft* Step 7. If Last_Subtract = true, R := R - Y. 891.1Smycroft* 901.1Smycroft* Step 8. Return signQ, last 7 bits of Q, and R as required. 911.1Smycroft* 921.1Smycroft* Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus, 931.1Smycroft* X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1), 941.1Smycroft* R := 0. Return signQ, last 7 bits of Q, and R. 951.1Smycroft* 961.1Smycroft 971.1SmycroftSREM_MOD IDNT 2,1 Motorola 040 Floating Point Software Package 981.1Smycroft 991.1Smycroft section 8 1001.1Smycroft 1011.1Smycroft include fpsp.h 1021.1Smycroft 1031.1SmycroftMod_Flag equ L_SCR3 1041.1SmycroftSignY equ FP_SCR3+4 1051.1SmycroftSignX equ FP_SCR3+8 1061.1SmycroftSignQ equ FP_SCR3+12 1071.1SmycroftSc_Flag equ FP_SCR4 1081.1Smycroft 1091.1SmycroftY equ FP_SCR1 1101.1SmycroftY_Hi equ Y+4 1111.1SmycroftY_Lo equ Y+8 1121.1Smycroft 1131.1SmycroftR equ FP_SCR2 1141.1SmycroftR_Hi equ R+4 1151.1SmycroftR_Lo equ R+8 1161.1Smycroft 1171.1Smycroft 1181.1SmycroftScale DC.L $00010000,$80000000,$00000000,$00000000 1191.1Smycroft 1201.1Smycroft xref t_avoid_unsupp 1211.1Smycroft 1221.1Smycroft xdef smod 1231.1Smycroftsmod: 1241.1Smycroft 1251.2Smycroft Clr.L Mod_Flag(a6) 1261.1Smycroft BRA.B Mod_Rem 1271.1Smycroft 1281.1Smycroft xdef srem 1291.1Smycroftsrem: 1301.1Smycroft 1311.1Smycroft Move.L #1,Mod_Flag(a6) 1321.1Smycroft 1331.1SmycroftMod_Rem: 1341.1Smycroft*..Save sign of X and Y 1351.1Smycroft MoveM.L D2-D7,-(A7) ...save data registers 1361.1Smycroft Move.W (A0),D3 1371.1Smycroft Move.W D3,SignY(a6) 1381.1Smycroft AndI.L #$00007FFF,D3 ...Y := |Y| 1391.1Smycroft 1401.1Smycroft* 1411.1Smycroft Move.L 4(A0),D4 1421.1Smycroft Move.L 8(A0),D5 ...(D3,D4,D5) is |Y| 1431.1Smycroft 1441.1Smycroft Tst.L D3 1451.1Smycroft BNE.B Y_Normal 1461.1Smycroft 1471.1Smycroft Move.L #$00003FFE,D3 ...$3FFD + 1 1481.1Smycroft Tst.L D4 1491.1Smycroft BNE.B HiY_not0 1501.1Smycroft 1511.1SmycroftHiY_0: 1521.1Smycroft Move.L D5,D4 1531.1Smycroft CLR.L D5 1541.1Smycroft SubI.L #32,D3 1551.1Smycroft CLR.L D6 1561.1Smycroft BFFFO D4{0:32},D6 1571.1Smycroft LSL.L D6,D4 1581.1Smycroft Sub.L D6,D3 ...(D3,D4,D5) is normalized 1591.1Smycroft* ...with bias $7FFD 1601.1Smycroft BRA.B Chk_X 1611.1Smycroft 1621.1SmycroftHiY_not0: 1631.1Smycroft CLR.L D6 1641.1Smycroft BFFFO D4{0:32},D6 1651.1Smycroft Sub.L D6,D3 1661.1Smycroft LSL.L D6,D4 1671.1Smycroft Move.L D5,D7 ...a copy of D5 1681.1Smycroft LSL.L D6,D5 1691.1Smycroft Neg.L D6 1701.1Smycroft AddI.L #32,D6 1711.1Smycroft LSR.L D6,D7 1721.1Smycroft Or.L D7,D4 ...(D3,D4,D5) normalized 1731.1Smycroft* ...with bias $7FFD 1741.1Smycroft BRA.B Chk_X 1751.1Smycroft 1761.1SmycroftY_Normal: 1771.1Smycroft AddI.L #$00003FFE,D3 ...(D3,D4,D5) normalized 1781.1Smycroft* ...with bias $7FFD 1791.1Smycroft 1801.1SmycroftChk_X: 1811.1Smycroft Move.W -12(A0),D0 1821.1Smycroft Move.W D0,SignX(a6) 1831.1Smycroft Move.W SignY(a6),D1 1841.1Smycroft EOr.L D0,D1 1851.1Smycroft AndI.L #$00008000,D1 1861.1Smycroft Move.W D1,SignQ(a6) ...sign(Q) obtained 1871.1Smycroft AndI.L #$00007FFF,D0 1881.1Smycroft Move.L -8(A0),D1 1891.1Smycroft Move.L -4(A0),D2 ...(D0,D1,D2) is |X| 1901.1Smycroft Tst.L D0 1911.1Smycroft BNE.B X_Normal 1921.1Smycroft Move.L #$00003FFE,D0 1931.1Smycroft Tst.L D1 1941.1Smycroft BNE.B HiX_not0 1951.1Smycroft 1961.1SmycroftHiX_0: 1971.1Smycroft Move.L D2,D1 1981.1Smycroft CLR.L D2 1991.1Smycroft SubI.L #32,D0 2001.1Smycroft CLR.L D6 2011.1Smycroft BFFFO D1{0:32},D6 2021.1Smycroft LSL.L D6,D1 2031.1Smycroft Sub.L D6,D0 ...(D0,D1,D2) is normalized 2041.1Smycroft* ...with bias $7FFD 2051.1Smycroft BRA.B Init 2061.1Smycroft 2071.1SmycroftHiX_not0: 2081.1Smycroft CLR.L D6 2091.1Smycroft BFFFO D1{0:32},D6 2101.1Smycroft Sub.L D6,D0 2111.1Smycroft LSL.L D6,D1 2121.1Smycroft Move.L D2,D7 ...a copy of D2 2131.1Smycroft LSL.L D6,D2 2141.1Smycroft Neg.L D6 2151.1Smycroft AddI.L #32,D6 2161.1Smycroft LSR.L D6,D7 2171.1Smycroft Or.L D7,D1 ...(D0,D1,D2) normalized 2181.1Smycroft* ...with bias $7FFD 2191.1Smycroft BRA.B Init 2201.1Smycroft 2211.1SmycroftX_Normal: 2221.1Smycroft AddI.L #$00003FFE,D0 ...(D0,D1,D2) normalized 2231.1Smycroft* ...with bias $7FFD 2241.1Smycroft 2251.1SmycroftInit: 2261.1Smycroft* 2271.1Smycroft Move.L D3,L_SCR1(a6) ...save biased expo(Y) 2281.1Smycroft move.l d0,L_SCR2(a6) ;save d0 2291.1Smycroft Sub.L D3,D0 ...L := expo(X)-expo(Y) 2301.1Smycroft* Move.L D0,L ...D0 is j 2311.1Smycroft CLR.L D6 ...D6 := carry <- 0 2321.1Smycroft CLR.L D3 ...D3 is Q 2331.1Smycroft MoveA.L #0,A1 ...A1 is k; j+k=L, Q=0 2341.1Smycroft 2351.1Smycroft*..(Carry,D1,D2) is R 2361.1Smycroft Tst.L D0 2371.1Smycroft BGE.B Mod_Loop 2381.1Smycroft 2391.1Smycroft*..expo(X) < expo(Y). Thus X = mod(X,Y) 2401.1Smycroft* 2411.1Smycroft move.l L_SCR2(a6),d0 ;restore d0 2421.1Smycroft BRA.W Get_Mod 2431.1Smycroft 2441.1Smycroft*..At this point R = 2^(-L)X; Q = 0; k = 0; and k+j = L 2451.1Smycroft 2461.1Smycroft 2471.1SmycroftMod_Loop: 2481.1Smycroft Tst.L D6 ...test carry bit 2491.1Smycroft BGT.B R_GT_Y 2501.1Smycroft 2511.1Smycroft*..At this point carry = 0, R = (D1,D2), Y = (D4,D5) 2521.1Smycroft Cmp.L D4,D1 ...compare hi(R) and hi(Y) 2531.1Smycroft BNE.B R_NE_Y 2541.1Smycroft Cmp.L D5,D2 ...compare lo(R) and lo(Y) 2551.1Smycroft BNE.B R_NE_Y 2561.1Smycroft 2571.1Smycroft*..At this point, R = Y 2581.1Smycroft BRA.W Rem_is_0 2591.1Smycroft 2601.1SmycroftR_NE_Y: 2611.1Smycroft*..use the borrow of the previous compare 2621.1Smycroft BCS.B R_LT_Y ...borrow is set iff R < Y 2631.1Smycroft 2641.1SmycroftR_GT_Y: 2651.1Smycroft*..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0 2661.1Smycroft*..and Y < (D1,D2) < 2Y. Either way, perform R - Y 2671.1Smycroft Sub.L D5,D2 ...lo(R) - lo(Y) 2681.1Smycroft SubX.L D4,D1 ...hi(R) - hi(Y) 2691.1Smycroft CLR.L D6 ...clear carry 2701.1Smycroft AddQ.L #1,D3 ...Q := Q + 1 2711.1Smycroft 2721.1SmycroftR_LT_Y: 2731.1Smycroft*..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0. 2741.1Smycroft Tst.L D0 ...see if j = 0. 2751.1Smycroft BEQ.B PostLoop 2761.1Smycroft 2771.1Smycroft Add.L D3,D3 ...Q := 2Q 2781.1Smycroft Add.L D2,D2 ...lo(R) = 2lo(R) 2791.2Smycroft AddX.L D1,D1 ...hi(R) = 2hi(R) + carry 2801.1Smycroft SCS D6 ...set Carry if 2(R) overflows 2811.1Smycroft AddQ.L #1,A1 ...k := k+1 2821.1Smycroft SubQ.L #1,D0 ...j := j - 1 2831.1Smycroft*..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y. 2841.1Smycroft 2851.1Smycroft BRA.B Mod_Loop 2861.1Smycroft 2871.1SmycroftPostLoop: 2881.1Smycroft*..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y. 2891.1Smycroft 2901.1Smycroft*..normalize R. 2911.1Smycroft Move.L L_SCR1(a6),D0 ...new biased expo of R 2921.1Smycroft Tst.L D1 2931.1Smycroft BNE.B HiR_not0 2941.1Smycroft 2951.1SmycroftHiR_0: 2961.1Smycroft Move.L D2,D1 2971.1Smycroft CLR.L D2 2981.1Smycroft SubI.L #32,D0 2991.1Smycroft CLR.L D6 3001.1Smycroft BFFFO D1{0:32},D6 3011.1Smycroft LSL.L D6,D1 3021.1Smycroft Sub.L D6,D0 ...(D0,D1,D2) is normalized 3031.1Smycroft* ...with bias $7FFD 3041.1Smycroft BRA.B Get_Mod 3051.1Smycroft 3061.1SmycroftHiR_not0: 3071.1Smycroft CLR.L D6 3081.1Smycroft BFFFO D1{0:32},D6 3091.1Smycroft BMI.B Get_Mod ...already normalized 3101.1Smycroft Sub.L D6,D0 3111.1Smycroft LSL.L D6,D1 3121.1Smycroft Move.L D2,D7 ...a copy of D2 3131.1Smycroft LSL.L D6,D2 3141.1Smycroft Neg.L D6 3151.1Smycroft AddI.L #32,D6 3161.1Smycroft LSR.L D6,D7 3171.1Smycroft Or.L D7,D1 ...(D0,D1,D2) normalized 3181.1Smycroft 3191.1Smycroft* 3201.1SmycroftGet_Mod: 3211.1Smycroft CmpI.L #$000041FE,D0 3221.1Smycroft BGE.B No_Scale 3231.1SmycroftDo_Scale: 3241.1Smycroft Move.W D0,R(a6) 3251.1Smycroft clr.w R+2(a6) 3261.1Smycroft Move.L D1,R_Hi(a6) 3271.1Smycroft Move.L D2,R_Lo(a6) 3281.1Smycroft Move.L L_SCR1(a6),D6 3291.1Smycroft Move.W D6,Y(a6) 3301.1Smycroft clr.w Y+2(a6) 3311.1Smycroft Move.L D4,Y_Hi(a6) 3321.1Smycroft Move.L D5,Y_Lo(a6) 3331.1Smycroft FMove.X R(a6),fp0 ...no exception 3341.1Smycroft Move.L #1,Sc_Flag(a6) 3351.1Smycroft BRA.B ModOrRem 3361.1SmycroftNo_Scale: 3371.1Smycroft Move.L D1,R_Hi(a6) 3381.1Smycroft Move.L D2,R_Lo(a6) 3391.1Smycroft SubI.L #$3FFE,D0 3401.1Smycroft Move.W D0,R(a6) 3411.1Smycroft clr.w R+2(a6) 3421.1Smycroft Move.L L_SCR1(a6),D6 3431.1Smycroft SubI.L #$3FFE,D6 3441.1Smycroft Move.L D6,L_SCR1(a6) 3451.1Smycroft FMove.X R(a6),fp0 3461.1Smycroft Move.W D6,Y(a6) 3471.1Smycroft Move.L D4,Y_Hi(a6) 3481.1Smycroft Move.L D5,Y_Lo(a6) 3491.2Smycroft Clr.L Sc_Flag(a6) 3501.1Smycroft 3511.1Smycroft* 3521.1Smycroft 3531.1Smycroft 3541.1SmycroftModOrRem: 3551.1Smycroft Move.L Mod_Flag(a6),D6 3561.1Smycroft BEQ.B Fix_Sign 3571.1Smycroft 3581.1Smycroft Move.L L_SCR1(a6),D6 ...new biased expo(Y) 3591.1Smycroft SubQ.L #1,D6 ...biased expo(Y/2) 3601.1Smycroft Cmp.L D6,D0 3611.1Smycroft BLT.B Fix_Sign 3621.1Smycroft BGT.B Last_Sub 3631.1Smycroft 3641.1Smycroft Cmp.L D4,D1 3651.1Smycroft BNE.B Not_EQ 3661.1Smycroft Cmp.L D5,D2 3671.1Smycroft BNE.B Not_EQ 3681.1Smycroft BRA.W Tie_Case 3691.1Smycroft 3701.1SmycroftNot_EQ: 3711.1Smycroft BCS.B Fix_Sign 3721.1Smycroft 3731.1SmycroftLast_Sub: 3741.1Smycroft* 3751.1Smycroft FSub.X Y(a6),fp0 ...no exceptions 3761.1Smycroft AddQ.L #1,D3 ...Q := Q + 1 3771.1Smycroft 3781.1Smycroft* 3791.1Smycroft 3801.1SmycroftFix_Sign: 3811.1Smycroft*..Get sign of X 3821.1Smycroft Move.W SignX(a6),D6 3831.1Smycroft BGE.B Get_Q 3841.1Smycroft FNeg.X fp0 3851.1Smycroft 3861.1Smycroft*..Get Q 3871.1Smycroft* 3881.1SmycroftGet_Q: 3891.1Smycroft clr.l d6 3901.1Smycroft Move.W SignQ(a6),D6 ...D6 is sign(Q) 3911.1Smycroft Move.L #8,D7 3921.1Smycroft LSR.L D7,D6 3931.1Smycroft AndI.L #$0000007F,D3 ...7 bits of Q 3941.1Smycroft Or.L D6,D3 ...sign and bits of Q 3951.1Smycroft Swap D3 3961.1Smycroft FMove.L fpsr,D6 3971.1Smycroft AndI.L #$FF00FFFF,D6 3981.1Smycroft Or.L D3,D6 3991.1Smycroft FMove.L D6,fpsr ...put Q in fpsr 4001.1Smycroft 4011.1Smycroft* 4021.1SmycroftRestore: 4031.1Smycroft MoveM.L (A7)+,D2-D7 4041.1Smycroft FMove.L USER_FPCR(a6),fpcr 4051.1Smycroft Move.L Sc_Flag(a6),D0 4061.1Smycroft BEQ.B Finish 4071.1Smycroft FMul.X Scale(pc),fp0 ...may cause underflow 4081.1Smycroft bra t_avoid_unsupp ;check for denorm as a 4091.1Smycroft* ;result of the scaling 4101.1Smycroft 4111.1SmycroftFinish: 4121.1Smycroft fmove.x fp0,fp0 ;capture exceptions & round 4131.1Smycroft rts 4141.1Smycroft 4151.1SmycroftRem_is_0: 4161.1Smycroft*..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1) 4171.1Smycroft AddQ.L #1,D3 4181.1Smycroft CmpI.L #8,D0 ...D0 is j 4191.1Smycroft BGE.B Q_Big 4201.1Smycroft 4211.1Smycroft LSL.L D0,D3 4221.1Smycroft BRA.B Set_R_0 4231.1Smycroft 4241.1SmycroftQ_Big: 4251.1Smycroft CLR.L D3 4261.1Smycroft 4271.1SmycroftSet_R_0: 4281.1Smycroft FMove.S #:00000000,fp0 4291.2Smycroft Clr.L Sc_Flag(a6) 4301.1Smycroft BRA.W Fix_Sign 4311.1Smycroft 4321.1SmycroftTie_Case: 4331.1Smycroft*..Check parity of Q 4341.1Smycroft Move.L D3,D6 4351.1Smycroft AndI.L #$00000001,D6 4361.1Smycroft Tst.L D6 4371.1Smycroft BEq.W Fix_Sign ...Q is even 4381.1Smycroft 4391.1Smycroft*..Q is odd, Q := Q + 1, signX := -signX 4401.1Smycroft AddQ.L #1,D3 4411.1Smycroft Move.W SignX(a6),D6 4421.1Smycroft EOrI.L #$00008000,D6 4431.1Smycroft Move.W D6,SignX(a6) 4441.1Smycroft BRA.W Fix_Sign 4451.1Smycroft 4461.1Smycroft End 447