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

VxWorks

开发平台:

C/C++

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