^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) | srem_mod.sa 3.1 12/10/90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) | The entry point sMOD computes the floating point MOD of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) | input values X and Y. The entry point sREM computes the floating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) | point (IEEE) REM of the input values X and Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) | INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) | -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) | Double-extended value Y is pointed to by address in register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) | A0. Double-extended value X is located in -12(A0). The values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) | of X and Y are both nonzero and finite; although either or both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) | of them can be denormalized. The special cases of zeros, NaNs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) | and infinities are handled elsewhere.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) | OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) | ------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) | FREM(X,Y) or FMOD(X,Y), depending on entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) | ALGORITHM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) | ---------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) | Step 1. Save and strip signs of X and Y: signX := sign(X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) | signY := sign(Y), X := |X|, Y := |Y|,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) | signQ := signX EOR signY. Record whether MOD or REM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) | is requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) | Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) | If (L < 0) then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) | R := X, go to Step 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) | else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) | R := 2^(-L)X, j := L.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) | endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) | Step 3. Perform MOD(X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) | 3.1 If R = Y, go to Step 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) | 3.2 If R > Y, then { R := R - Y, Q := Q + 1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) | 3.3 If j = 0, go to Step 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) | 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) | Step 3.1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) | Step 4. At this point, R = X - QY = MOD(X,Y). Set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) | Last_Subtract := false (used in Step 7 below). If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) | MOD is requested, go to Step 6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) | Step 5. R = MOD(X,Y), but REM(X,Y) is requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) | 5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) | Step 6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) | 5.2 If R > Y/2, then { set Last_Subtract := true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) | Q := Q + 1, Y := signY*Y }. Go to Step 6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) | 5.3 This is the tricky case of R = Y/2. If Q is odd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) | then { Q := Q + 1, signX := -signX }.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) | Step 6. R := signX*R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) | Step 7. If Last_Subtract = true, R := R - Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) | Step 8. Return signQ, last 7 bits of Q, and R as required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) | Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) | X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) | R := 0. Return signQ, last 7 bits of Q, and R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) | Copyright (C) Motorola, Inc. 1990
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) | All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) | For details on the license for this file, please see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) | file, README, in this same directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) SREM_MOD: |idnt 2,1 | Motorola 040 Floating Point Software Package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) |section 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #include "fpsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .set Mod_Flag,L_SCR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .set SignY,FP_SCR3+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .set SignX,FP_SCR3+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .set SignQ,FP_SCR3+12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .set Sc_Flag,FP_SCR4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .set Y,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .set Y_Hi,Y+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .set Y_Lo,Y+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .set R,FP_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .set R_Hi,R+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .set R_Lo,R+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) Scale: .long 0x00010000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) |xref t_avoid_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .global smod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) smod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) movel #0,Mod_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) bras Mod_Rem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .global srem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) srem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) movel #1,Mod_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) Mod_Rem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) |..Save sign of X and Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) moveml %d2-%d7,-(%a7) | ...save data registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) movew (%a0),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) movew %d3,SignY(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) andil #0x00007FFF,%d3 | ...Y := |Y|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) movel 4(%a0),%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) movel 8(%a0),%d5 | ...(D3,D4,D5) is |Y|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) tstl %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) bnes Y_Normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) movel #0x00003FFE,%d3 | ...$3FFD + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) tstl %d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) bnes HiY_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) HiY_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) movel %d5,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) clrl %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) subil #32,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) clrl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) bfffo %d4{#0:#32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) lsll %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) subl %d6,%d3 | ...(D3,D4,D5) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) | ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) bras Chk_X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) HiY_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) clrl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) bfffo %d4{#0:#32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) subl %d6,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) lsll %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) movel %d5,%d7 | ...a copy of D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) lsll %d6,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) negl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) addil #32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) lsrl %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) orl %d7,%d4 | ...(D3,D4,D5) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) | ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) bras Chk_X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) Y_Normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) addil #0x00003FFE,%d3 | ...(D3,D4,D5) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) | ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) Chk_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) movew -12(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) movew %d0,SignX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) movew SignY(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) eorl %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) andil #0x00008000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) movew %d1,SignQ(%a6) | ...sign(Q) obtained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) andil #0x00007FFF,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) movel -8(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) movel -4(%a0),%d2 | ...(D0,D1,D2) is |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) tstl %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) bnes X_Normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) movel #0x00003FFE,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) tstl %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) bnes HiX_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) HiX_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) movel %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) clrl %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) subil #32,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) clrl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) bfffo %d1{#0:#32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) lsll %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) subl %d6,%d0 | ...(D0,D1,D2) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) | ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) bras Init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) HiX_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) clrl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) bfffo %d1{#0:#32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) subl %d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) lsll %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) movel %d2,%d7 | ...a copy of D2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) lsll %d6,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) negl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) addil #32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) lsrl %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) orl %d7,%d1 | ...(D0,D1,D2) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) | ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) bras Init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) X_Normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) addil #0x00003FFE,%d0 | ...(D0,D1,D2) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) | ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) Init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) movel %d3,L_SCR1(%a6) | ...save biased expo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) movel %d0,L_SCR2(%a6) |save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) subl %d3,%d0 | ...L := expo(X)-expo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) | Move.L D0,L ...D0 is j
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) clrl %d6 | ...D6 := carry <- 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) clrl %d3 | ...D3 is Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) moveal #0,%a1 | ...A1 is k; j+k=L, Q=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) |..(Carry,D1,D2) is R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) tstl %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) bges Mod_Loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) |..expo(X) < expo(Y). Thus X = mod(X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) movel L_SCR2(%a6),%d0 |restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) bra Get_Mod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) |..At this point R = 2^(-L)X; Q = 0; k = 0; and k+j = L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) Mod_Loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) tstl %d6 | ...test carry bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) bgts R_GT_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) |..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) cmpl %d4,%d1 | ...compare hi(R) and hi(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) bnes R_NE_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) cmpl %d5,%d2 | ...compare lo(R) and lo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) bnes R_NE_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) |..At this point, R = Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) bra Rem_is_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) R_NE_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) |..use the borrow of the previous compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) bcss R_LT_Y | ...borrow is set iff R < Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) R_GT_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) |..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) |..and Y < (D1,D2) < 2Y. Either way, perform R - Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) subl %d5,%d2 | ...lo(R) - lo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) subxl %d4,%d1 | ...hi(R) - hi(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) clrl %d6 | ...clear carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) addql #1,%d3 | ...Q := Q + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) R_LT_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) |..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) tstl %d0 | ...see if j = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) beqs PostLoop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) addl %d3,%d3 | ...Q := 2Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) addl %d2,%d2 | ...lo(R) = 2lo(R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) roxll #1,%d1 | ...hi(R) = 2hi(R) + carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) scs %d6 | ...set Carry if 2(R) overflows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) addql #1,%a1 | ...k := k+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) subql #1,%d0 | ...j := j - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) |..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) bras Mod_Loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) PostLoop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) |..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) |..normalize R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) movel L_SCR1(%a6),%d0 | ...new biased expo of R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) tstl %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) bnes HiR_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) HiR_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) movel %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) clrl %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) subil #32,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) clrl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) bfffo %d1{#0:#32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) lsll %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) subl %d6,%d0 | ...(D0,D1,D2) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) | ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) bras Get_Mod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) HiR_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) clrl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) bfffo %d1{#0:#32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) bmis Get_Mod | ...already normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) subl %d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) lsll %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) movel %d2,%d7 | ...a copy of D2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) lsll %d6,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) negl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) addil #32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) lsrl %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) orl %d7,%d1 | ...(D0,D1,D2) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) Get_Mod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) cmpil #0x000041FE,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) bges No_Scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) Do_Scale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) movew %d0,R(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) clrw R+2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) movel %d1,R_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) movel %d2,R_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) movel L_SCR1(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) movew %d6,Y(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) clrw Y+2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) movel %d4,Y_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) movel %d5,Y_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) fmovex R(%a6),%fp0 | ...no exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) movel #1,Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) bras ModOrRem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) No_Scale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) movel %d1,R_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) movel %d2,R_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) subil #0x3FFE,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) movew %d0,R(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) clrw R+2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) movel L_SCR1(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) subil #0x3FFE,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) movel %d6,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) fmovex R(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) movew %d6,Y(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) movel %d4,Y_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) movel %d5,Y_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) movel #0,Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ModOrRem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) movel Mod_Flag(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) beqs Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) movel L_SCR1(%a6),%d6 | ...new biased expo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) subql #1,%d6 | ...biased expo(Y/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) cmpl %d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) blts Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) bgts Last_Sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) cmpl %d4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) bnes Not_EQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) cmpl %d5,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) bnes Not_EQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) bra Tie_Case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) Not_EQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) bcss Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) Last_Sub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) fsubx Y(%a6),%fp0 | ...no exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) addql #1,%d3 | ...Q := Q + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) Fix_Sign:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) |..Get sign of X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) movew SignX(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) bges Get_Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) fnegx %fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) |..Get Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) Get_Q:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) clrl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) movew SignQ(%a6),%d6 | ...D6 is sign(Q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) movel #8,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) lsrl %d7,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) andil #0x0000007F,%d3 | ...7 bits of Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) orl %d6,%d3 | ...sign and bits of Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) swap %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) fmovel %fpsr,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) andil #0xFF00FFFF,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) orl %d3,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) fmovel %d6,%fpsr | ...put Q in fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) Restore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) moveml (%a7)+,%d2-%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) fmovel USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) movel Sc_Flag(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) beqs Finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) fmulx Scale(%pc),%fp0 | ...may cause underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) bra t_avoid_unsupp |check for denorm as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) | ;result of the scaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) Finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) fmovex %fp0,%fp0 |capture exceptions & round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) Rem_is_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) |..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) addql #1,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) cmpil #8,%d0 | ...D0 is j
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) bges Q_Big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) lsll %d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) bras Set_R_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) Q_Big:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) clrl %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) Set_R_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) fmoves #0x00000000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) movel #0,Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) bra Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) Tie_Case:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) |..Check parity of Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) movel %d3,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) andil #0x00000001,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) tstl %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) beq Fix_Sign | ...Q is even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) |..Q is odd, Q := Q + 1, signX := -signX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) addql #1,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) movew SignX(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) eoril #0x00008000,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) movew %d6,SignX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) bra Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) |end