source: rtems/c/src/lib/libcpu/m68k/m68040/fpsp/srem_mod.s @ f9b93da

4.104.114.84.95
Last change on this file since f9b93da was f9b93da, checked in by Joel Sherrill <joel.sherrill@…>, on 04/16/97 at 17:33:04

Added the MC68040 Floating Point Support Package. This was ported
to RTEMS by Eric Norum. It is freely distributable and was acquired
from the Motorola WWW site. More info is in the FPSP README.

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