l_srem_mod.s
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:12k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* l_srem_mods.s - Motorola 68040 FP modulo/remainder routines (LIB) */
  2. /* Copyright 1991-1993 Wind River Systems, Inc. */
  3. .data
  4. .globl _copyright_wind_river
  5. .long _copyright_wind_river
  6. /*
  7. modification history
  8. --------------------
  9. 01f,21jul93,kdl  added .text (SPR #2372).
  10. 01e,23aug92,jcf  changed bxxx to jxx.
  11. 01d,26may92,rrr  the tree shuffle
  12. 01c,10jan92,kdl  added modification history; general cleanup.
  13. 01b,01jan92,jcf  reversed order of cmp <reg>,<reg>
  14. 01a,15aug91,kdl  original version, from Motorola FPSP v2.0.
  15. */
  16. /*
  17. DESCRIPTION
  18. srem_modsa 3.1 12/10/90
  19.  WIND RIVER MODIFICATION HISTORY
  20.       The entry point sMOD computes the floating point MOD of the
  21.       input values X and Y. The entry point sREM computes the floating
  22.       point (IEEE) REM of the input values X and Y.
  23.       INPUT
  24.       -----
  25.       Double-extended value Y is pointed to by address in register
  26.       A0. Double-extended value X is located in A0@(-12). The values
  27.       of X and Y are both nonzero and finite|  although either or both
  28.       of them can be denormalized. The special cases of zeros, NaNs,
  29.       and infinities are handled elsewhere.
  30.       OUTPUT
  31.       ------
  32.       FREM(X,Y) or FMOD(X,Y), depending on entry point.
  33.        ALGORITHM
  34.        ---------
  35.        Step 1.  Save and strip signs of X and Y: signX := sign(X),
  36.                 signY := sign(Y), X := |X|, Y := |Y|,
  37.                 signQ := signX EOR signY. Record whether MOD or REM
  38.                 is requested.
  39.        Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.
  40.                 If (L < 0) then
  41.                    R := X, go to Step 4.
  42.                 else
  43.                    R := 2^(-L)X, j := L.
  44.                 endif
  45.        Step 3.  Perform MOD(X,Y)
  46.             3.1 If R = Y, go to Step 9.
  47.             3.2 If R > Y, then { R := R - Y, Q := Q + 1}
  48.             3.3 If j = 0, go to Step 4.
  49.             3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to
  50.                 Step 3.1.
  51.        Step 4.  At this point, R = X - QY = MOD(X,Y). Set
  52.                 Last_Subtract := false (used in Step 7 below). If
  53.                 MOD is requested, go to Step 6.
  54.        Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.
  55.             5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to
  56.                 Step 6.
  57.             5.2 If R > Y/2, then { set Last_Subtract := true,
  58.                 Q := Q + 1, Y := signY*Y }. Go to Step 6.
  59.             5.3 This is the tricky case of R = Y/2. If Q is odd,
  60.                 then { Q := Q + 1, signX := -signX }.
  61.        Step 6.  R := signX*R.
  62.        Step 7.  If Last_Subtract = true, R := R - Y.
  63.        Step 8.  Return signQ, last 7 bits of Q, and R as required.
  64.        Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,
  65.                 X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),
  66.                 R := 0. Return signQ, last 7 bits of Q, and R.
  67. Copyright (C) Motorola, Inc. 1990
  68. All Rights Reserved
  69. THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
  70. The copyright notice above does not evidence any
  71. actual or intended publication of such source code.
  72. SREM_MOD    idnt    2,1 Motorola 040 Floating Point Software Package
  73. section    8
  74. NOMANUAL
  75. */
  76. #include "fpsp040L.h"
  77. #define Mod_Flag   L_SCR3
  78. #define SignY      FP_SCR3+4
  79. #define SignX      FP_SCR3+8
  80. #define SignQ      FP_SCR3+12
  81. #define Sc_Flag    FP_SCR4
  82. #define Y          FP_SCR1
  83. #define Y_Hi       Y+4
  84. #define Y_Lo       Y+8
  85. #define R          FP_SCR2
  86. #define R_Hi       R+4
  87. #define R_Lo       R+8
  88. Scale:     .long 0x00010000,0x80000000,0x00000000,0x00000000
  89. | xref __l_t_avoid_unsupp
  90. .text
  91.         .globl        __l_smod
  92. __l_smod:
  93.    movel               #0,a6@(Mod_Flag)
  94.    jra                 Mod_Rem
  95.         .globl        __l_srem
  96. __l_srem:
  97.    movel               #1,a6@(Mod_Flag)
  98. Mod_Rem:
  99. |..Save sign of X and Y
  100.    moveml              d2-d7,A7@-     |...save data registers
  101.    movew               A0@,d3
  102.    movew               d3,a6@(SignY)
  103.    andil               #0x00007FFF,d3   |...Y := |Y|
  104. |
  105.    movel               A0@(4),d4
  106.    movel               A0@(8),d5        |...(D3,d4,d5) is |Y|
  107.    tstl                d3
  108.    jne                 Y_Normal
  109.    movel               #0x00003FFE,d3 |...0x3FFD + 1
  110.    tstl                d4
  111.    jne                 HiY_not0
  112. HiY_0:
  113.    movel               d5,d4
  114.    clrl                d5
  115.    subil               #32,d3
  116.    clrl                d6
  117.    bfffo                d4{#0:#32},d6
  118.    lsll                d6,d4
  119.    subl                d6,d3           |...(D3,d4,d5) is normalized
  120. |                                       |...with bias 0x7FFD
  121.    jra                 Chk_X
  122. HiY_not0:
  123.    clrl                d6
  124.    bfffo                d4{#0:#32},d6
  125.    subl                d6,d3
  126.    lsll                d6,d4
  127.    movel               d5,d7           |...a copy of d5
  128.    lsll                d6,d5
  129.    negl                d6
  130.    addil               #32,d6
  131.    lsrl                d6,d7
  132.    orl                 d7,d4           |...(D3,d4,d5) normalized
  133. |                                       |...with bias 0x7FFD
  134.    jra                 Chk_X
  135. Y_Normal:
  136.    addil               #0x00003FFE,d3   |...(D3,d4,d5) normalized
  137. |                                       |...with bias 0x7FFD
  138. Chk_X:
  139.    movew               A0@(-12),d0
  140.    movew               d0,a6@(SignX)
  141.    movew               a6@(SignY),d1
  142.    eorl                d0,d1
  143.    andil               #0x00008000,d1
  144.    movew               d1,a6@(SignQ) |...sign(Q) obtained
  145.    andil               #0x00007FFF,d0
  146.    movel               A0@(-8),d1
  147.    movel               A0@(-4),d2       |...(D0,d1,d2) is |X|
  148.    tstl                d0
  149.    jne                 X_Normal
  150.    movel               #0x00003FFE,d0
  151.    tstl                d1
  152.    jne                 HiX_not0
  153. HiX_0:
  154.    movel               d2,d1
  155.    clrl                d2
  156.    subil               #32,d0
  157.    clrl                d6
  158.    bfffo                d1{#0:#32},d6
  159.    lsll                d6,d1
  160.    subl                d6,d0           |...(D0,d1,d2) is normalized
  161. |                                       |...with bias 0x7FFD
  162.    jra                 Init
  163. HiX_not0:
  164.    clrl                d6
  165.    bfffo                d1{#0:#32},d6
  166.    subl                d6,d0
  167.    lsll                d6,d1
  168.    movel               d2,d7           |...a copy of d2
  169.    lsll                d6,d2
  170.    negl                d6
  171.    addil               #32,d6
  172.    lsrl                d6,d7
  173.    orl                 d7,d1           |...(D0,d1,d2) normalized
  174. |                                       |...with bias 0x7FFD
  175.    jra                 Init
  176. X_Normal:
  177.    addil               #0x00003FFE,d0   |...(D0,d1,d2) normalized
  178. |                                       |...with bias 0x7FFD
  179. Init:
  180. |
  181.    movel               d3,a6@(L_SCR1)   |...save biased expo(Y)
  182.    movel d0,a6@(L_SCR2) | save d0
  183.    subl                d3,d0           |...l := expo(X)-expo(Y)
  184. |   Movel               D0,L            |...D0 is j
  185.    clrl                d6              |...D6 := carry <- 0
  186.    clrl                d3              |...D3 is Q
  187.    moveal              #0,a1           |...A1 is k|  j+k=L, Q=0
  188. |..(Carry,D1,D2) is R
  189.    tstl                d0
  190.    jge                 Mod_Loop
  191. |..expo(X) < expo(Y). Thus X = mod(X,Y)
  192. |
  193.    movel a6@(L_SCR2),d0 | restore d0
  194.    jra                 Get_Mod
  195. |..At this point  R = 2^(-L)X|  Q = 0|  k = 0|  and  k+j = L
  196. Mod_Loop:
  197.    tstl                d6              |...test carry bit
  198.    jgt                 R_GT_Y
  199. |..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
  200.    cmpl                d1,d4           |...compare hi(R) and hi(Y)
  201.    jne                 R_NE_Y
  202.    cmpl                d2,d5           |...compare lo(R) and lo(Y)
  203.    jne                 R_NE_Y
  204. |..At this point, R = Y
  205.    jra                 Rem_is_0
  206. R_NE_Y:
  207. |..use the borrow of the previous compare
  208.    jcs                 R_LT_Y          |...borrow is set iff R < Y
  209. R_GT_Y:
  210. |..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
  211. |..and Y < (D1,D2) < 2Y. Either way, perform R - Y
  212.    subl                d5,d2           |...lo(R) - lo(Y)
  213.    subxl               d4,d1           |...hi(R) - hi(Y)
  214.    clrl                d6              |...clear carry
  215.    addql               #1,d3           |...Q := Q + 1
  216. R_LT_Y:
  217. |..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY|  k+j = L|  j >= 0.
  218.    tstl                d0              |...see if j = 0.
  219.    jeq                 PostLoop
  220.    addl                d3,d3           |...Q := 2Q
  221.    addl                d2,d2           |...lo(R) = 2lo(R)
  222.    roxll               #1,d1           |...hi(R) = 2hi(R) + carry
  223.    scs                 d6              |...set Carry if 2(R) overflows
  224.    addql               #1,a1           |...k := k+1
  225.    subql               #1,d0           |...j := j - 1
  226. |..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
  227.    jra                 Mod_Loop
  228. PostLoop:
  229. |..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
  230. |..normalize R.
  231.    movel               a6@(L_SCR1),d0           |...new biased expo of R
  232.    tstl                d1
  233.    jne                 HiR_not0
  234. HiR_0:
  235.    movel               d2,d1
  236.    clrl                d2
  237.    subil               #32,d0
  238.    clrl                d6
  239.    bfffo                d1{#0:#32},d6
  240.    lsll                d6,d1
  241.    subl                d6,d0           |...(D0,d1,d2) is normalized
  242. |                                       |...with bias 0x7FFD
  243.    jra                 Get_Mod
  244. HiR_not0:
  245.    clrl                d6
  246.    bfffo                d1{#0:#32},d6
  247.    jmi                 Get_Mod         |...already normalized
  248.    subl                d6,d0
  249.    lsll                d6,d1
  250.    movel               d2,d7           |...a copy of d2
  251.    lsll                d6,d2
  252.    negl                d6
  253.    addil               #32,d6
  254.    lsrl                d6,d7
  255.    orl                 d7,d1           |...(D0,d1,d2) normalized
  256. |
  257. Get_Mod:
  258.    cmpil #0x000041FE,d0
  259.    jge  No_Scale
  260. Do_Scale:
  261.    movew d0,a6@(R)
  262.    clrw a6@(R+2)
  263.    movel d1,a6@(R_Hi)
  264.    movel d2,a6@(R_Lo)
  265.    movel a6@(L_SCR1),d6
  266.    movew d6,a6@(Y)
  267.    clrw a6@(Y+2)
  268.    movel d4,a6@(Y_Hi)
  269.    movel d5,a6@(Y_Lo)
  270.    fmovex a6@(R),fp0 |...no exception
  271.    movel #1,a6@(Sc_Flag)
  272.    jra  ModOrRem
  273. No_Scale:
  274.    movel d1,a6@(R_Hi)
  275.    movel d2,a6@(R_Lo)
  276.    subil #0x3FFE,d0
  277.    movew d0,a6@(R)
  278.    clrw a6@(R+2)
  279.    movel a6@(L_SCR1),d6
  280.    subil #0x3FFE,d6
  281.    movel d6,a6@(L_SCR1)
  282.    fmovex a6@(R),fp0
  283.    movew d6,a6@(Y)
  284.    movel d4,a6@(Y_Hi)
  285.    movel d5,a6@(Y_Lo)
  286.    movel #0,a6@(Sc_Flag)
  287. |
  288. ModOrRem:
  289.    movel               a6@(Mod_Flag),d6
  290.    jeq                 Fix_Sign
  291.    movel               a6@(L_SCR1),d6           |...new biased expo(Y)
  292.    subql               #1,d6           |...biased expo(Y/2)
  293.    cmpl                d0,d6
  294.    jlt                 Fix_Sign
  295.    jgt                 Last_Sub
  296.    cmpl                d1,d4
  297.    jne                 Not_EQ
  298.    cmpl                d2,d5
  299.    jne                 Not_EQ
  300.    jra                 Tie_Case
  301. Not_EQ:
  302.    jcs                 Fix_Sign
  303. Last_Sub:
  304. |
  305.    fsubx a6@(Y),fp0 |...no exceptions
  306.    addql               #1,d3           |...Q := Q + 1
  307. |
  308. Fix_Sign:
  309. |..Get sign of X
  310.    movew               a6@(SignX),d6
  311.    jge  Get_Q
  312.    fnegx fp0
  313. |..Get Q
  314. |
  315. Get_Q:
  316.    clrl d6
  317.    movew               a6@(SignQ),d6        |...D6 is sign(Q)
  318.    movel               #8,d7
  319.    lsrl                d7,d6
  320.    andil               #0x0000007F,d3   |...7 bits of Q
  321.    orl                 d6,d3           |...sign and bits of Q
  322.    swap                 d3
  323.    fmovel              fpsr,d6
  324.    andil               #0xFF00FFFF,d6
  325.    orl                 d3,d6
  326.    fmovel              d6,fpsr         |...put Q in fpsr
  327. |
  328. Restore:
  329.    moveml              A7@+,d2-d7
  330.    fmovel              a6@(USER_FPCR),fpcr
  331.    movel               a6@(Sc_Flag),d0
  332.    jeq                 Finish
  333.    fmulx pc@(Scale),fp0 |...may cause underflow
  334.    jra  __l_t_avoid_unsupp | check for denorm as a
  335. | | result of the scaling
  336. Finish:
  337. fmovex fp0,fp0 | capture exceptions # round
  338. rts
  339. Rem_is_0:
  340. |..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
  341.    addql               #1,d3
  342.    cmpil               #8,d0           |...D0 is j
  343.    jge                 Q_Big
  344.    lsll                d0,d3
  345.    jra                 Set_R_0
  346. Q_Big:
  347.    clrl                d3
  348. Set_R_0:
  349.    .long 0xf23c4400,0x00000000  /* fmoves &0x00000000,fp0 */
  350.    movel #0,a6@(Sc_Flag)
  351.    jra                 Fix_Sign
  352. Tie_Case:
  353. |..Check parity of Q
  354.    movel               d3,d6
  355.    andil               #0x00000001,d6
  356.    tstl                d6
  357.    jeq                 Fix_Sign |...Q is even
  358. |..Q is odd, Q := Q + 1, signX := -signX
  359.    addql               #1,d3
  360.    movew               a6@(SignX),d6
  361.    eoril               #0x00008000,d6
  362.    movew               d6,a6@(SignX)
  363.    jra                 Fix_Sign
  364. |   end