config.host: (arm*-*-freebsd*): Remove.
[platform/upstream/gcc.git] / libgcc / config / arm / ieee754-df.S
1 /* ieee754-df.S double-precision floating point support for ARM
2
3    Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2012
4    Free Software Foundation, Inc.
5    Contributed by Nicolas Pitre (nico@cam.org)
6
7    This file is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by the
9    Free Software Foundation; either version 3, or (at your option) any
10    later version.
11
12    This file is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16
17    Under Section 7 of GPL version 3, you are granted additional
18    permissions described in the GCC Runtime Library Exception, version
19    3.1, as published by the Free Software Foundation.
20
21    You should have received a copy of the GNU General Public License and
22    a copy of the GCC Runtime Library Exception along with this program;
23    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24    <http://www.gnu.org/licenses/>.  */
25
26 /*
27  * Notes: 
28  * 
29  * The goal of this code is to be as fast as possible.  This is
30  * not meant to be easy to understand for the casual reader.
31  * For slightly simpler code please see the single precision version
32  * of this file.
33  * 
34  * Only the default rounding mode is intended for best performances.
35  * Exceptions aren't supported yet, but that can be added quite easily
36  * if necessary without impacting performances.
37  */
38
39
40 #ifndef __ARMEB__
41 #define xl r0
42 #define xh r1
43 #define yl r2
44 #define yh r3
45 #else
46 #define xh r0
47 #define xl r1
48 #define yh r2
49 #define yl r3
50 #endif
51
52
53 #ifdef L_arm_negdf2
54
55 ARM_FUNC_START negdf2
56 ARM_FUNC_ALIAS aeabi_dneg negdf2
57
58         @ flip sign bit
59         eor     xh, xh, #0x80000000
60         RET
61
62         FUNC_END aeabi_dneg
63         FUNC_END negdf2
64
65 #endif
66
67 #ifdef L_arm_addsubdf3
68
69 ARM_FUNC_START aeabi_drsub
70
71         eor     xh, xh, #0x80000000     @ flip sign bit of first arg
72         b       1f      
73
74 ARM_FUNC_START subdf3
75 ARM_FUNC_ALIAS aeabi_dsub subdf3
76
77         eor     yh, yh, #0x80000000     @ flip sign bit of second arg
78 #if defined(__INTERWORKING_STUBS__)
79         b       1f                      @ Skip Thumb-code prologue
80 #endif
81
82 ARM_FUNC_START adddf3
83 ARM_FUNC_ALIAS aeabi_dadd adddf3
84
85 1:      do_push {r4, r5, lr}
86
87         @ Look for zeroes, equal values, INF, or NAN.
88         shift1  lsl, r4, xh, #1
89         shift1  lsl, r5, yh, #1
90         teq     r4, r5
91         do_it   eq
92         teqeq   xl, yl
93         do_it   ne, ttt
94         COND(orr,s,ne)  ip, r4, xl
95         COND(orr,s,ne)  ip, r5, yl
96         COND(mvn,s,ne)  ip, r4, asr #21
97         COND(mvn,s,ne)  ip, r5, asr #21
98         beq     LSYM(Lad_s)
99
100         @ Compute exponent difference.  Make largest exponent in r4,
101         @ corresponding arg in xh-xl, and positive exponent difference in r5.
102         shift1  lsr, r4, r4, #21
103         rsbs    r5, r4, r5, lsr #21
104         do_it   lt
105         rsblt   r5, r5, #0
106         ble     1f
107         add     r4, r4, r5
108         eor     yl, xl, yl
109         eor     yh, xh, yh
110         eor     xl, yl, xl
111         eor     xh, yh, xh
112         eor     yl, xl, yl
113         eor     yh, xh, yh
114 1:
115         @ If exponent difference is too large, return largest argument
116         @ already in xh-xl.  We need up to 54 bit to handle proper rounding
117         @ of 0x1p54 - 1.1.
118         cmp     r5, #54
119         do_it   hi
120         RETLDM  "r4, r5" hi
121
122         @ Convert mantissa to signed integer.
123         tst     xh, #0x80000000
124         mov     xh, xh, lsl #12
125         mov     ip, #0x00100000
126         orr     xh, ip, xh, lsr #12
127         beq     1f
128 #if defined(__thumb2__)
129         negs    xl, xl
130         sbc     xh, xh, xh, lsl #1
131 #else
132         rsbs    xl, xl, #0
133         rsc     xh, xh, #0
134 #endif
135 1:
136         tst     yh, #0x80000000
137         mov     yh, yh, lsl #12
138         orr     yh, ip, yh, lsr #12
139         beq     1f
140 #if defined(__thumb2__)
141         negs    yl, yl
142         sbc     yh, yh, yh, lsl #1
143 #else
144         rsbs    yl, yl, #0
145         rsc     yh, yh, #0
146 #endif
147 1:
148         @ If exponent == difference, one or both args were denormalized.
149         @ Since this is not common case, rescale them off line.
150         teq     r4, r5
151         beq     LSYM(Lad_d)
152 LSYM(Lad_x):
153
154         @ Compensate for the exponent overlapping the mantissa MSB added later
155         sub     r4, r4, #1
156
157         @ Shift yh-yl right per r5, add to xh-xl, keep leftover bits into ip.
158         rsbs    lr, r5, #32
159         blt     1f
160         shift1  lsl, ip, yl, lr
161         shiftop adds xl xl yl lsr r5 yl
162         adc     xh, xh, #0
163         shiftop adds xl xl yh lsl lr yl
164         shiftop adcs xh xh yh asr r5 yh
165         b       2f
166 1:      sub     r5, r5, #32
167         add     lr, lr, #32
168         cmp     yl, #1
169         shift1  lsl,ip, yh, lr
170         do_it   cs
171         orrcs   ip, ip, #2              @ 2 not 1, to allow lsr #1 later
172         shiftop adds xl xl yh asr r5 yh
173         adcs    xh, xh, yh, asr #31
174 2:
175         @ We now have a result in xh-xl-ip.
176         @ Keep absolute value in xh-xl-ip, sign in r5 (the n bit was set above)
177         and     r5, xh, #0x80000000
178         bpl     LSYM(Lad_p)
179 #if defined(__thumb2__)
180         mov     lr, #0
181         negs    ip, ip
182         sbcs    xl, lr, xl
183         sbc     xh, lr, xh
184 #else
185         rsbs    ip, ip, #0
186         rscs    xl, xl, #0
187         rsc     xh, xh, #0
188 #endif
189
190         @ Determine how to normalize the result.
191 LSYM(Lad_p):
192         cmp     xh, #0x00100000
193         bcc     LSYM(Lad_a)
194         cmp     xh, #0x00200000
195         bcc     LSYM(Lad_e)
196
197         @ Result needs to be shifted right.
198         movs    xh, xh, lsr #1
199         movs    xl, xl, rrx
200         mov     ip, ip, rrx
201         add     r4, r4, #1
202
203         @ Make sure we did not bust our exponent.
204         mov     r2, r4, lsl #21
205         cmn     r2, #(2 << 21)
206         bcs     LSYM(Lad_o)
207
208         @ Our result is now properly aligned into xh-xl, remaining bits in ip.
209         @ Round with MSB of ip. If halfway between two numbers, round towards
210         @ LSB of xl = 0.
211         @ Pack final result together.
212 LSYM(Lad_e):
213         cmp     ip, #0x80000000
214         do_it   eq
215         COND(mov,s,eq)  ip, xl, lsr #1
216         adcs    xl, xl, #0
217         adc     xh, xh, r4, lsl #20
218         orr     xh, xh, r5
219         RETLDM  "r4, r5"
220
221         @ Result must be shifted left and exponent adjusted.
222 LSYM(Lad_a):
223         movs    ip, ip, lsl #1
224         adcs    xl, xl, xl
225         adc     xh, xh, xh
226         tst     xh, #0x00100000
227         sub     r4, r4, #1
228         bne     LSYM(Lad_e)
229
230         @ No rounding necessary since ip will always be 0 at this point.
231 LSYM(Lad_l):
232
233 #if __ARM_ARCH__ < 5
234
235         teq     xh, #0
236         movne   r3, #20
237         moveq   r3, #52
238         moveq   xh, xl
239         moveq   xl, #0
240         mov     r2, xh
241         cmp     r2, #(1 << 16)
242         movhs   r2, r2, lsr #16
243         subhs   r3, r3, #16
244         cmp     r2, #(1 << 8)
245         movhs   r2, r2, lsr #8
246         subhs   r3, r3, #8
247         cmp     r2, #(1 << 4)
248         movhs   r2, r2, lsr #4
249         subhs   r3, r3, #4
250         cmp     r2, #(1 << 2)
251         subhs   r3, r3, #2
252         sublo   r3, r3, r2, lsr #1
253         sub     r3, r3, r2, lsr #3
254
255 #else
256
257         teq     xh, #0
258         do_it   eq, t
259         moveq   xh, xl
260         moveq   xl, #0
261         clz     r3, xh
262         do_it   eq
263         addeq   r3, r3, #32
264         sub     r3, r3, #11
265
266 #endif
267
268         @ determine how to shift the value.
269         subs    r2, r3, #32
270         bge     2f
271         adds    r2, r2, #12
272         ble     1f
273
274         @ shift value left 21 to 31 bits, or actually right 11 to 1 bits
275         @ since a register switch happened above.
276         add     ip, r2, #20
277         rsb     r2, r2, #12
278         shift1  lsl, xl, xh, ip
279         shift1  lsr, xh, xh, r2
280         b       3f
281
282         @ actually shift value left 1 to 20 bits, which might also represent
283         @ 32 to 52 bits if counting the register switch that happened earlier.
284 1:      add     r2, r2, #20
285 2:      do_it   le
286         rsble   ip, r2, #32
287         shift1  lsl, xh, xh, r2
288 #if defined(__thumb2__)
289         lsr     ip, xl, ip
290         itt     le
291         orrle   xh, xh, ip
292         lslle   xl, xl, r2
293 #else
294         orrle   xh, xh, xl, lsr ip
295         movle   xl, xl, lsl r2
296 #endif
297
298         @ adjust exponent accordingly.
299 3:      subs    r4, r4, r3
300         do_it   ge, tt
301         addge   xh, xh, r4, lsl #20
302         orrge   xh, xh, r5
303         RETLDM  "r4, r5" ge
304
305         @ Exponent too small, denormalize result.
306         @ Find out proper shift value.
307         mvn     r4, r4
308         subs    r4, r4, #31
309         bge     2f
310         adds    r4, r4, #12
311         bgt     1f
312
313         @ shift result right of 1 to 20 bits, sign is in r5.
314         add     r4, r4, #20
315         rsb     r2, r4, #32
316         shift1  lsr, xl, xl, r4
317         shiftop orr xl xl xh lsl r2 yh
318         shiftop orr xh r5 xh lsr r4 yh
319         RETLDM  "r4, r5"
320
321         @ shift result right of 21 to 31 bits, or left 11 to 1 bits after
322         @ a register switch from xh to xl.
323 1:      rsb     r4, r4, #12
324         rsb     r2, r4, #32
325         shift1  lsr, xl, xl, r2
326         shiftop orr xl xl xh lsl r4 yh
327         mov     xh, r5
328         RETLDM  "r4, r5"
329
330         @ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
331         @ from xh to xl.
332 2:      shift1  lsr, xl, xh, r4
333         mov     xh, r5
334         RETLDM  "r4, r5"
335
336         @ Adjust exponents for denormalized arguments.
337         @ Note that r4 must not remain equal to 0.
338 LSYM(Lad_d):
339         teq     r4, #0
340         eor     yh, yh, #0x00100000
341         do_it   eq, te
342         eoreq   xh, xh, #0x00100000
343         addeq   r4, r4, #1
344         subne   r5, r5, #1
345         b       LSYM(Lad_x)
346
347
348 LSYM(Lad_s):
349         mvns    ip, r4, asr #21
350         do_it   ne
351         COND(mvn,s,ne)  ip, r5, asr #21
352         beq     LSYM(Lad_i)
353
354         teq     r4, r5
355         do_it   eq
356         teqeq   xl, yl
357         beq     1f
358
359         @ Result is x + 0.0 = x or 0.0 + y = y.
360         orrs    ip, r4, xl
361         do_it   eq, t
362         moveq   xh, yh
363         moveq   xl, yl
364         RETLDM  "r4, r5"
365
366 1:      teq     xh, yh
367
368         @ Result is x - x = 0.
369         do_it   ne, tt
370         movne   xh, #0
371         movne   xl, #0
372         RETLDM  "r4, r5" ne
373
374         @ Result is x + x = 2x.
375         movs    ip, r4, lsr #21
376         bne     2f
377         movs    xl, xl, lsl #1
378         adcs    xh, xh, xh
379         do_it   cs
380         orrcs   xh, xh, #0x80000000
381         RETLDM  "r4, r5"
382 2:      adds    r4, r4, #(2 << 21)
383         do_it   cc, t
384         addcc   xh, xh, #(1 << 20)
385         RETLDM  "r4, r5" cc
386         and     r5, xh, #0x80000000
387
388         @ Overflow: return INF.
389 LSYM(Lad_o):
390         orr     xh, r5, #0x7f000000
391         orr     xh, xh, #0x00f00000
392         mov     xl, #0
393         RETLDM  "r4, r5"
394
395         @ At least one of x or y is INF/NAN.
396         @   if xh-xl != INF/NAN: return yh-yl (which is INF/NAN)
397         @   if yh-yl != INF/NAN: return xh-xl (which is INF/NAN)
398         @   if either is NAN: return NAN
399         @   if opposite sign: return NAN
400         @   otherwise return xh-xl (which is INF or -INF)
401 LSYM(Lad_i):
402         mvns    ip, r4, asr #21
403         do_it   ne, te
404         movne   xh, yh
405         movne   xl, yl
406         COND(mvn,s,eq)  ip, r5, asr #21
407         do_it   ne, t
408         movne   yh, xh
409         movne   yl, xl
410         orrs    r4, xl, xh, lsl #12
411         do_it   eq, te
412         COND(orr,s,eq)  r5, yl, yh, lsl #12
413         teqeq   xh, yh
414         orrne   xh, xh, #0x00080000     @ quiet NAN
415         RETLDM  "r4, r5"
416
417         FUNC_END aeabi_dsub
418         FUNC_END subdf3
419         FUNC_END aeabi_dadd
420         FUNC_END adddf3
421
422 ARM_FUNC_START floatunsidf
423 ARM_FUNC_ALIAS aeabi_ui2d floatunsidf
424
425         teq     r0, #0
426         do_it   eq, t
427         moveq   r1, #0
428         RETc(eq)
429         do_push {r4, r5, lr}
430         mov     r4, #0x400              @ initial exponent
431         add     r4, r4, #(52-1 - 1)
432         mov     r5, #0                  @ sign bit is 0
433         .ifnc   xl, r0
434         mov     xl, r0
435         .endif
436         mov     xh, #0
437         b       LSYM(Lad_l)
438
439         FUNC_END aeabi_ui2d
440         FUNC_END floatunsidf
441
442 ARM_FUNC_START floatsidf
443 ARM_FUNC_ALIAS aeabi_i2d floatsidf
444
445         teq     r0, #0
446         do_it   eq, t
447         moveq   r1, #0
448         RETc(eq)
449         do_push {r4, r5, lr}
450         mov     r4, #0x400              @ initial exponent
451         add     r4, r4, #(52-1 - 1)
452         ands    r5, r0, #0x80000000     @ sign bit in r5
453         do_it   mi
454         rsbmi   r0, r0, #0              @ absolute value
455         .ifnc   xl, r0
456         mov     xl, r0
457         .endif
458         mov     xh, #0
459         b       LSYM(Lad_l)
460
461         FUNC_END aeabi_i2d
462         FUNC_END floatsidf
463
464 ARM_FUNC_START extendsfdf2
465 ARM_FUNC_ALIAS aeabi_f2d extendsfdf2
466
467         movs    r2, r0, lsl #1          @ toss sign bit
468         mov     xh, r2, asr #3          @ stretch exponent
469         mov     xh, xh, rrx             @ retrieve sign bit
470         mov     xl, r2, lsl #28         @ retrieve remaining bits
471         do_it   ne, ttt
472         COND(and,s,ne)  r3, r2, #0xff000000     @ isolate exponent
473         teqne   r3, #0xff000000         @ if not 0, check if INF or NAN
474         eorne   xh, xh, #0x38000000     @ fixup exponent otherwise.
475         RETc(ne)                        @ and return it.
476
477         teq     r2, #0                  @ if actually 0
478         do_it   ne, e
479         teqne   r3, #0xff000000         @ or INF or NAN
480         RETc(eq)                        @ we are done already.
481
482         @ value was denormalized.  We can normalize it now.
483         do_push {r4, r5, lr}
484         mov     r4, #0x380              @ setup corresponding exponent
485         and     r5, xh, #0x80000000     @ move sign bit in r5
486         bic     xh, xh, #0x80000000
487         b       LSYM(Lad_l)
488
489         FUNC_END aeabi_f2d
490         FUNC_END extendsfdf2
491
492 ARM_FUNC_START floatundidf
493 ARM_FUNC_ALIAS aeabi_ul2d floatundidf
494
495         orrs    r2, r0, r1
496         do_it   eq
497         RETc(eq)
498
499         do_push {r4, r5, lr}
500
501         mov     r5, #0
502         b       2f
503
504 ARM_FUNC_START floatdidf
505 ARM_FUNC_ALIAS aeabi_l2d floatdidf
506
507         orrs    r2, r0, r1
508         do_it   eq
509         RETc(eq)
510
511         do_push {r4, r5, lr}
512
513         ands    r5, ah, #0x80000000     @ sign bit in r5
514         bpl     2f
515 #if defined(__thumb2__)
516         negs    al, al
517         sbc     ah, ah, ah, lsl #1
518 #else
519         rsbs    al, al, #0
520         rsc     ah, ah, #0
521 #endif
522 2:
523         mov     r4, #0x400              @ initial exponent
524         add     r4, r4, #(52-1 - 1)
525
526         @ If FP word order does not match integer word order, swap the words.
527         .ifnc   xh, ah
528         mov     ip, al
529         mov     xh, ah
530         mov     xl, ip
531         .endif
532
533         movs    ip, xh, lsr #22
534         beq     LSYM(Lad_p)
535
536         @ The value is too big.  Scale it down a bit...
537         mov     r2, #3
538         movs    ip, ip, lsr #3
539         do_it   ne
540         addne   r2, r2, #3
541         movs    ip, ip, lsr #3
542         do_it   ne
543         addne   r2, r2, #3
544         add     r2, r2, ip, lsr #3
545
546         rsb     r3, r2, #32
547         shift1  lsl, ip, xl, r3
548         shift1  lsr, xl, xl, r2
549         shiftop orr xl xl xh lsl r3 lr
550         shift1  lsr, xh, xh, r2
551         add     r4, r4, r2
552         b       LSYM(Lad_p)
553
554         FUNC_END floatdidf
555         FUNC_END aeabi_l2d
556         FUNC_END floatundidf
557         FUNC_END aeabi_ul2d
558
559 #endif /* L_addsubdf3 */
560
561 #ifdef L_arm_muldivdf3
562
563 ARM_FUNC_START muldf3
564 ARM_FUNC_ALIAS aeabi_dmul muldf3
565         do_push {r4, r5, r6, lr}
566
567         @ Mask out exponents, trap any zero/denormal/INF/NAN.
568         mov     ip, #0xff
569         orr     ip, ip, #0x700
570         ands    r4, ip, xh, lsr #20
571         do_it   ne, tte
572         COND(and,s,ne)  r5, ip, yh, lsr #20
573         teqne   r4, ip
574         teqne   r5, ip
575         bleq    LSYM(Lml_s)
576
577         @ Add exponents together
578         add     r4, r4, r5
579
580         @ Determine final sign.
581         eor     r6, xh, yh
582
583         @ Convert mantissa to unsigned integer.
584         @ If power of two, branch to a separate path.
585         bic     xh, xh, ip, lsl #21
586         bic     yh, yh, ip, lsl #21
587         orrs    r5, xl, xh, lsl #12
588         do_it   ne
589         COND(orr,s,ne)  r5, yl, yh, lsl #12
590         orr     xh, xh, #0x00100000
591         orr     yh, yh, #0x00100000
592         beq     LSYM(Lml_1)
593
594 #if __ARM_ARCH__ < 4
595
596         @ Put sign bit in r6, which will be restored in yl later.
597         and   r6, r6, #0x80000000
598
599         @ Well, no way to make it shorter without the umull instruction.
600         stmfd   sp!, {r6, r7, r8, r9, sl, fp}
601         mov     r7, xl, lsr #16
602         mov     r8, yl, lsr #16
603         mov     r9, xh, lsr #16
604         mov     sl, yh, lsr #16
605         bic     xl, xl, r7, lsl #16
606         bic     yl, yl, r8, lsl #16
607         bic     xh, xh, r9, lsl #16
608         bic     yh, yh, sl, lsl #16
609         mul     ip, xl, yl
610         mul     fp, xl, r8
611         mov     lr, #0
612         adds    ip, ip, fp, lsl #16
613         adc     lr, lr, fp, lsr #16
614         mul     fp, r7, yl
615         adds    ip, ip, fp, lsl #16
616         adc     lr, lr, fp, lsr #16
617         mul     fp, xl, sl
618         mov     r5, #0
619         adds    lr, lr, fp, lsl #16
620         adc     r5, r5, fp, lsr #16
621         mul     fp, r7, yh
622         adds    lr, lr, fp, lsl #16
623         adc     r5, r5, fp, lsr #16
624         mul     fp, xh, r8
625         adds    lr, lr, fp, lsl #16
626         adc     r5, r5, fp, lsr #16
627         mul     fp, r9, yl
628         adds    lr, lr, fp, lsl #16
629         adc     r5, r5, fp, lsr #16
630         mul     fp, xh, sl
631         mul     r6, r9, sl
632         adds    r5, r5, fp, lsl #16
633         adc     r6, r6, fp, lsr #16
634         mul     fp, r9, yh
635         adds    r5, r5, fp, lsl #16
636         adc     r6, r6, fp, lsr #16
637         mul     fp, xl, yh
638         adds    lr, lr, fp
639         mul     fp, r7, sl
640         adcs    r5, r5, fp
641         mul     fp, xh, yl
642         adc     r6, r6, #0
643         adds    lr, lr, fp
644         mul     fp, r9, r8
645         adcs    r5, r5, fp
646         mul     fp, r7, r8
647         adc     r6, r6, #0
648         adds    lr, lr, fp
649         mul     fp, xh, yh
650         adcs    r5, r5, fp
651         adc     r6, r6, #0
652         ldmfd   sp!, {yl, r7, r8, r9, sl, fp}
653
654 #else
655
656         @ Here is the actual multiplication.
657         umull   ip, lr, xl, yl
658         mov     r5, #0
659         umlal   lr, r5, xh, yl
660         and     yl, r6, #0x80000000
661         umlal   lr, r5, xl, yh
662         mov     r6, #0
663         umlal   r5, r6, xh, yh
664
665 #endif
666
667         @ The LSBs in ip are only significant for the final rounding.
668         @ Fold them into lr.
669         teq     ip, #0
670         do_it   ne
671         orrne   lr, lr, #1
672
673         @ Adjust result upon the MSB position.
674         sub     r4, r4, #0xff
675         cmp     r6, #(1 << (20-11))
676         sbc     r4, r4, #0x300
677         bcs     1f
678         movs    lr, lr, lsl #1
679         adcs    r5, r5, r5
680         adc     r6, r6, r6
681 1:
682         @ Shift to final position, add sign to result.
683         orr     xh, yl, r6, lsl #11
684         orr     xh, xh, r5, lsr #21
685         mov     xl, r5, lsl #11
686         orr     xl, xl, lr, lsr #21
687         mov     lr, lr, lsl #11
688
689         @ Check exponent range for under/overflow.
690         subs    ip, r4, #(254 - 1)
691         do_it   hi
692         cmphi   ip, #0x700
693         bhi     LSYM(Lml_u)
694
695         @ Round the result, merge final exponent.
696         cmp     lr, #0x80000000
697         do_it   eq
698         COND(mov,s,eq)  lr, xl, lsr #1
699         adcs    xl, xl, #0
700         adc     xh, xh, r4, lsl #20
701         RETLDM  "r4, r5, r6"
702
703         @ Multiplication by 0x1p*: let''s shortcut a lot of code.
704 LSYM(Lml_1):
705         and     r6, r6, #0x80000000
706         orr     xh, r6, xh
707         orr     xl, xl, yl
708         eor     xh, xh, yh
709         subs    r4, r4, ip, lsr #1
710         do_it   gt, tt
711         COND(rsb,s,gt)  r5, r4, ip
712         orrgt   xh, xh, r4, lsl #20
713         RETLDM  "r4, r5, r6" gt
714
715         @ Under/overflow: fix things up for the code below.
716         orr     xh, xh, #0x00100000
717         mov     lr, #0
718         subs    r4, r4, #1
719
720 LSYM(Lml_u):
721         @ Overflow?
722         bgt     LSYM(Lml_o)
723
724         @ Check if denormalized result is possible, otherwise return signed 0.
725         cmn     r4, #(53 + 1)
726         do_it   le, tt
727         movle   xl, #0
728         bicle   xh, xh, #0x7fffffff
729         RETLDM  "r4, r5, r6" le
730
731         @ Find out proper shift value.
732         rsb     r4, r4, #0
733         subs    r4, r4, #32
734         bge     2f
735         adds    r4, r4, #12
736         bgt     1f
737
738         @ shift result right of 1 to 20 bits, preserve sign bit, round, etc.
739         add     r4, r4, #20
740         rsb     r5, r4, #32
741         shift1  lsl, r3, xl, r5
742         shift1  lsr, xl, xl, r4
743         shiftop orr xl xl xh lsl r5 r2
744         and     r2, xh, #0x80000000
745         bic     xh, xh, #0x80000000
746         adds    xl, xl, r3, lsr #31
747         shiftop adc xh r2 xh lsr r4 r6
748         orrs    lr, lr, r3, lsl #1
749         do_it   eq
750         biceq   xl, xl, r3, lsr #31
751         RETLDM  "r4, r5, r6"
752
753         @ shift result right of 21 to 31 bits, or left 11 to 1 bits after
754         @ a register switch from xh to xl. Then round.
755 1:      rsb     r4, r4, #12
756         rsb     r5, r4, #32
757         shift1  lsl, r3, xl, r4
758         shift1  lsr, xl, xl, r5
759         shiftop orr xl xl xh lsl r4 r2
760         bic     xh, xh, #0x7fffffff
761         adds    xl, xl, r3, lsr #31
762         adc     xh, xh, #0
763         orrs    lr, lr, r3, lsl #1
764         do_it   eq
765         biceq   xl, xl, r3, lsr #31
766         RETLDM  "r4, r5, r6"
767
768         @ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
769         @ from xh to xl.  Leftover bits are in r3-r6-lr for rounding.
770 2:      rsb     r5, r4, #32
771         shiftop orr lr lr xl lsl r5 r2
772         shift1  lsr, r3, xl, r4
773         shiftop orr r3 r3 xh lsl r5 r2
774         shift1  lsr, xl, xh, r4
775         bic     xh, xh, #0x7fffffff
776         shiftop bic xl xl xh lsr r4 r2
777         add     xl, xl, r3, lsr #31
778         orrs    lr, lr, r3, lsl #1
779         do_it   eq
780         biceq   xl, xl, r3, lsr #31
781         RETLDM  "r4, r5, r6"
782
783         @ One or both arguments are denormalized.
784         @ Scale them leftwards and preserve sign bit.
785 LSYM(Lml_d):
786         teq     r4, #0
787         bne     2f
788         and     r6, xh, #0x80000000
789 1:      movs    xl, xl, lsl #1
790         adc     xh, xh, xh
791         tst     xh, #0x00100000
792         do_it   eq
793         subeq   r4, r4, #1
794         beq     1b
795         orr     xh, xh, r6
796         teq     r5, #0
797         do_it   ne
798         RETc(ne)
799 2:      and     r6, yh, #0x80000000
800 3:      movs    yl, yl, lsl #1
801         adc     yh, yh, yh
802         tst     yh, #0x00100000
803         do_it   eq
804         subeq   r5, r5, #1
805         beq     3b
806         orr     yh, yh, r6
807         RET
808
809 LSYM(Lml_s):
810         @ Isolate the INF and NAN cases away
811         teq     r4, ip
812         and     r5, ip, yh, lsr #20
813         do_it   ne
814         teqne   r5, ip
815         beq     1f
816
817         @ Here, one or more arguments are either denormalized or zero.
818         orrs    r6, xl, xh, lsl #1
819         do_it   ne
820         COND(orr,s,ne)  r6, yl, yh, lsl #1
821         bne     LSYM(Lml_d)
822
823         @ Result is 0, but determine sign anyway.
824 LSYM(Lml_z):
825         eor     xh, xh, yh
826         and     xh, xh, #0x80000000
827         mov     xl, #0
828         RETLDM  "r4, r5, r6"
829
830 1:      @ One or both args are INF or NAN.
831         orrs    r6, xl, xh, lsl #1
832         do_it   eq, te
833         moveq   xl, yl
834         moveq   xh, yh
835         COND(orr,s,ne)  r6, yl, yh, lsl #1
836         beq     LSYM(Lml_n)             @ 0 * INF or INF * 0 -> NAN
837         teq     r4, ip
838         bne     1f
839         orrs    r6, xl, xh, lsl #12
840         bne     LSYM(Lml_n)             @ NAN * <anything> -> NAN
841 1:      teq     r5, ip
842         bne     LSYM(Lml_i)
843         orrs    r6, yl, yh, lsl #12
844         do_it   ne, t
845         movne   xl, yl
846         movne   xh, yh
847         bne     LSYM(Lml_n)             @ <anything> * NAN -> NAN
848
849         @ Result is INF, but we need to determine its sign.
850 LSYM(Lml_i):
851         eor     xh, xh, yh
852
853         @ Overflow: return INF (sign already in xh).
854 LSYM(Lml_o):
855         and     xh, xh, #0x80000000
856         orr     xh, xh, #0x7f000000
857         orr     xh, xh, #0x00f00000
858         mov     xl, #0
859         RETLDM  "r4, r5, r6"
860
861         @ Return a quiet NAN.
862 LSYM(Lml_n):
863         orr     xh, xh, #0x7f000000
864         orr     xh, xh, #0x00f80000
865         RETLDM  "r4, r5, r6"
866
867         FUNC_END aeabi_dmul
868         FUNC_END muldf3
869
870 ARM_FUNC_START divdf3
871 ARM_FUNC_ALIAS aeabi_ddiv divdf3
872         
873         do_push {r4, r5, r6, lr}
874
875         @ Mask out exponents, trap any zero/denormal/INF/NAN.
876         mov     ip, #0xff
877         orr     ip, ip, #0x700
878         ands    r4, ip, xh, lsr #20
879         do_it   ne, tte
880         COND(and,s,ne)  r5, ip, yh, lsr #20
881         teqne   r4, ip
882         teqne   r5, ip
883         bleq    LSYM(Ldv_s)
884
885         @ Subtract divisor exponent from dividend''s.
886         sub     r4, r4, r5
887
888         @ Preserve final sign into lr.
889         eor     lr, xh, yh
890
891         @ Convert mantissa to unsigned integer.
892         @ Dividend -> r5-r6, divisor -> yh-yl.
893         orrs    r5, yl, yh, lsl #12
894         mov     xh, xh, lsl #12
895         beq     LSYM(Ldv_1)
896         mov     yh, yh, lsl #12
897         mov     r5, #0x10000000
898         orr     yh, r5, yh, lsr #4
899         orr     yh, yh, yl, lsr #24
900         mov     yl, yl, lsl #8
901         orr     r5, r5, xh, lsr #4
902         orr     r5, r5, xl, lsr #24
903         mov     r6, xl, lsl #8
904
905         @ Initialize xh with final sign bit.
906         and     xh, lr, #0x80000000
907
908         @ Ensure result will land to known bit position.
909         @ Apply exponent bias accordingly.
910         cmp     r5, yh
911         do_it   eq
912         cmpeq   r6, yl
913         adc     r4, r4, #(255 - 2)
914         add     r4, r4, #0x300
915         bcs     1f
916         movs    yh, yh, lsr #1
917         mov     yl, yl, rrx
918 1:
919         @ Perform first subtraction to align result to a nibble.
920         subs    r6, r6, yl
921         sbc     r5, r5, yh
922         movs    yh, yh, lsr #1
923         mov     yl, yl, rrx
924         mov     xl, #0x00100000
925         mov     ip, #0x00080000
926
927         @ The actual division loop.
928 1:      subs    lr, r6, yl
929         sbcs    lr, r5, yh
930         do_it   cs, tt
931         subcs   r6, r6, yl
932         movcs   r5, lr
933         orrcs   xl, xl, ip
934         movs    yh, yh, lsr #1
935         mov     yl, yl, rrx
936         subs    lr, r6, yl
937         sbcs    lr, r5, yh
938         do_it   cs, tt
939         subcs   r6, r6, yl
940         movcs   r5, lr
941         orrcs   xl, xl, ip, lsr #1
942         movs    yh, yh, lsr #1
943         mov     yl, yl, rrx
944         subs    lr, r6, yl
945         sbcs    lr, r5, yh
946         do_it   cs, tt
947         subcs   r6, r6, yl
948         movcs   r5, lr
949         orrcs   xl, xl, ip, lsr #2
950         movs    yh, yh, lsr #1
951         mov     yl, yl, rrx
952         subs    lr, r6, yl
953         sbcs    lr, r5, yh
954         do_it   cs, tt
955         subcs   r6, r6, yl
956         movcs   r5, lr
957         orrcs   xl, xl, ip, lsr #3
958
959         orrs    lr, r5, r6
960         beq     2f
961         mov     r5, r5, lsl #4
962         orr     r5, r5, r6, lsr #28
963         mov     r6, r6, lsl #4
964         mov     yh, yh, lsl #3
965         orr     yh, yh, yl, lsr #29
966         mov     yl, yl, lsl #3
967         movs    ip, ip, lsr #4
968         bne     1b
969
970         @ We are done with a word of the result.
971         @ Loop again for the low word if this pass was for the high word.
972         tst     xh, #0x00100000
973         bne     3f
974         orr     xh, xh, xl
975         mov     xl, #0
976         mov     ip, #0x80000000
977         b       1b
978 2:
979         @ Be sure result starts in the high word.
980         tst     xh, #0x00100000
981         do_it   eq, t
982         orreq   xh, xh, xl
983         moveq   xl, #0
984 3:
985         @ Check exponent range for under/overflow.
986         subs    ip, r4, #(254 - 1)
987         do_it   hi
988         cmphi   ip, #0x700
989         bhi     LSYM(Lml_u)
990
991         @ Round the result, merge final exponent.
992         subs    ip, r5, yh
993         do_it   eq, t
994         COND(sub,s,eq)  ip, r6, yl
995         COND(mov,s,eq)  ip, xl, lsr #1
996         adcs    xl, xl, #0
997         adc     xh, xh, r4, lsl #20
998         RETLDM  "r4, r5, r6"
999
1000         @ Division by 0x1p*: shortcut a lot of code.
1001 LSYM(Ldv_1):
1002         and     lr, lr, #0x80000000
1003         orr     xh, lr, xh, lsr #12
1004         adds    r4, r4, ip, lsr #1
1005         do_it   gt, tt
1006         COND(rsb,s,gt)  r5, r4, ip
1007         orrgt   xh, xh, r4, lsl #20
1008         RETLDM  "r4, r5, r6" gt
1009
1010         orr     xh, xh, #0x00100000
1011         mov     lr, #0
1012         subs    r4, r4, #1
1013         b       LSYM(Lml_u)
1014
1015         @ Result mightt need to be denormalized: put remainder bits
1016         @ in lr for rounding considerations.
1017 LSYM(Ldv_u):
1018         orr     lr, r5, r6
1019         b       LSYM(Lml_u)
1020
1021         @ One or both arguments is either INF, NAN or zero.
1022 LSYM(Ldv_s):
1023         and     r5, ip, yh, lsr #20
1024         teq     r4, ip
1025         do_it   eq
1026         teqeq   r5, ip
1027         beq     LSYM(Lml_n)             @ INF/NAN / INF/NAN -> NAN
1028         teq     r4, ip
1029         bne     1f
1030         orrs    r4, xl, xh, lsl #12
1031         bne     LSYM(Lml_n)             @ NAN / <anything> -> NAN
1032         teq     r5, ip
1033         bne     LSYM(Lml_i)             @ INF / <anything> -> INF
1034         mov     xl, yl
1035         mov     xh, yh
1036         b       LSYM(Lml_n)             @ INF / (INF or NAN) -> NAN
1037 1:      teq     r5, ip
1038         bne     2f
1039         orrs    r5, yl, yh, lsl #12
1040         beq     LSYM(Lml_z)             @ <anything> / INF -> 0
1041         mov     xl, yl
1042         mov     xh, yh
1043         b       LSYM(Lml_n)             @ <anything> / NAN -> NAN
1044 2:      @ If both are nonzero, we need to normalize and resume above.
1045         orrs    r6, xl, xh, lsl #1
1046         do_it   ne
1047         COND(orr,s,ne)  r6, yl, yh, lsl #1
1048         bne     LSYM(Lml_d)
1049         @ One or both arguments are 0.
1050         orrs    r4, xl, xh, lsl #1
1051         bne     LSYM(Lml_i)             @ <non_zero> / 0 -> INF
1052         orrs    r5, yl, yh, lsl #1
1053         bne     LSYM(Lml_z)             @ 0 / <non_zero> -> 0
1054         b       LSYM(Lml_n)             @ 0 / 0 -> NAN
1055
1056         FUNC_END aeabi_ddiv
1057         FUNC_END divdf3
1058
1059 #endif /* L_muldivdf3 */
1060
1061 #ifdef L_arm_cmpdf2
1062
1063 @ Note: only r0 (return value) and ip are clobbered here.
1064
1065 ARM_FUNC_START gtdf2
1066 ARM_FUNC_ALIAS gedf2 gtdf2
1067         mov     ip, #-1
1068         b       1f
1069
1070 ARM_FUNC_START ltdf2
1071 ARM_FUNC_ALIAS ledf2 ltdf2
1072         mov     ip, #1
1073         b       1f
1074
1075 ARM_FUNC_START cmpdf2
1076 ARM_FUNC_ALIAS nedf2 cmpdf2
1077 ARM_FUNC_ALIAS eqdf2 cmpdf2
1078         mov     ip, #1                  @ how should we specify unordered here?
1079
1080 1:      str     ip, [sp, #-4]!
1081
1082         @ Trap any INF/NAN first.
1083         mov     ip, xh, lsl #1
1084         mvns    ip, ip, asr #21
1085         mov     ip, yh, lsl #1
1086         do_it   ne
1087         COND(mvn,s,ne)  ip, ip, asr #21
1088         beq     3f
1089
1090         @ Test for equality.
1091         @ Note that 0.0 is equal to -0.0.
1092 2:      add     sp, sp, #4
1093         orrs    ip, xl, xh, lsl #1      @ if x == 0.0 or -0.0
1094         do_it   eq, e
1095         COND(orr,s,eq)  ip, yl, yh, lsl #1      @ and y == 0.0 or -0.0
1096         teqne   xh, yh                  @ or xh == yh
1097         do_it   eq, tt
1098         teqeq   xl, yl                  @ and xl == yl
1099         moveq   r0, #0                  @ then equal.
1100         RETc(eq)
1101
1102         @ Clear C flag
1103         cmn     r0, #0
1104
1105         @ Compare sign, 
1106         teq     xh, yh
1107
1108         @ Compare values if same sign
1109         do_it   pl
1110         cmppl   xh, yh
1111         do_it   eq
1112         cmpeq   xl, yl
1113
1114         @ Result:
1115         do_it   cs, e
1116         movcs   r0, yh, asr #31
1117         mvncc   r0, yh, asr #31
1118         orr     r0, r0, #1
1119         RET
1120
1121         @ Look for a NAN.
1122 3:      mov     ip, xh, lsl #1
1123         mvns    ip, ip, asr #21
1124         bne     4f
1125         orrs    ip, xl, xh, lsl #12
1126         bne     5f                      @ x is NAN
1127 4:      mov     ip, yh, lsl #1
1128         mvns    ip, ip, asr #21
1129         bne     2b
1130         orrs    ip, yl, yh, lsl #12
1131         beq     2b                      @ y is not NAN
1132 5:      ldr     r0, [sp], #4            @ unordered return code
1133         RET
1134
1135         FUNC_END gedf2
1136         FUNC_END gtdf2
1137         FUNC_END ledf2
1138         FUNC_END ltdf2
1139         FUNC_END nedf2
1140         FUNC_END eqdf2
1141         FUNC_END cmpdf2
1142
1143 ARM_FUNC_START aeabi_cdrcmple
1144
1145         mov     ip, r0
1146         mov     r0, r2
1147         mov     r2, ip
1148         mov     ip, r1
1149         mov     r1, r3
1150         mov     r3, ip
1151         b       6f
1152         
1153 ARM_FUNC_START aeabi_cdcmpeq
1154 ARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq
1155
1156         @ The status-returning routines are required to preserve all
1157         @ registers except ip, lr, and cpsr.
1158 6:      do_push {r0, lr}
1159         ARM_CALL cmpdf2
1160         @ Set the Z flag correctly, and the C flag unconditionally.
1161         cmp     r0, #0
1162         @ Clear the C flag if the return value was -1, indicating
1163         @ that the first operand was smaller than the second.
1164         do_it   mi
1165         cmnmi   r0, #0
1166         RETLDM  "r0"
1167
1168         FUNC_END aeabi_cdcmple
1169         FUNC_END aeabi_cdcmpeq
1170         FUNC_END aeabi_cdrcmple
1171         
1172 ARM_FUNC_START  aeabi_dcmpeq
1173
1174         str     lr, [sp, #-8]!
1175         ARM_CALL aeabi_cdcmple
1176         do_it   eq, e
1177         moveq   r0, #1  @ Equal to.
1178         movne   r0, #0  @ Less than, greater than, or unordered.
1179         RETLDM
1180
1181         FUNC_END aeabi_dcmpeq
1182
1183 ARM_FUNC_START  aeabi_dcmplt
1184
1185         str     lr, [sp, #-8]!
1186         ARM_CALL aeabi_cdcmple
1187         do_it   cc, e
1188         movcc   r0, #1  @ Less than.
1189         movcs   r0, #0  @ Equal to, greater than, or unordered.
1190         RETLDM
1191
1192         FUNC_END aeabi_dcmplt
1193
1194 ARM_FUNC_START  aeabi_dcmple
1195
1196         str     lr, [sp, #-8]!
1197         ARM_CALL aeabi_cdcmple
1198         do_it   ls, e
1199         movls   r0, #1  @ Less than or equal to.
1200         movhi   r0, #0  @ Greater than or unordered.
1201         RETLDM
1202
1203         FUNC_END aeabi_dcmple
1204
1205 ARM_FUNC_START  aeabi_dcmpge
1206
1207         str     lr, [sp, #-8]!
1208         ARM_CALL aeabi_cdrcmple
1209         do_it   ls, e
1210         movls   r0, #1  @ Operand 2 is less than or equal to operand 1.
1211         movhi   r0, #0  @ Operand 2 greater than operand 1, or unordered.
1212         RETLDM
1213
1214         FUNC_END aeabi_dcmpge
1215
1216 ARM_FUNC_START  aeabi_dcmpgt
1217
1218         str     lr, [sp, #-8]!
1219         ARM_CALL aeabi_cdrcmple
1220         do_it   cc, e
1221         movcc   r0, #1  @ Operand 2 is less than operand 1.
1222         movcs   r0, #0  @ Operand 2 is greater than or equal to operand 1,
1223                         @ or they are unordered.
1224         RETLDM
1225
1226         FUNC_END aeabi_dcmpgt
1227
1228 #endif /* L_cmpdf2 */
1229
1230 #ifdef L_arm_unorddf2
1231
1232 ARM_FUNC_START unorddf2
1233 ARM_FUNC_ALIAS aeabi_dcmpun unorddf2
1234
1235         mov     ip, xh, lsl #1
1236         mvns    ip, ip, asr #21
1237         bne     1f
1238         orrs    ip, xl, xh, lsl #12
1239         bne     3f                      @ x is NAN
1240 1:      mov     ip, yh, lsl #1
1241         mvns    ip, ip, asr #21
1242         bne     2f
1243         orrs    ip, yl, yh, lsl #12
1244         bne     3f                      @ y is NAN
1245 2:      mov     r0, #0                  @ arguments are ordered.
1246         RET
1247
1248 3:      mov     r0, #1                  @ arguments are unordered.
1249         RET
1250
1251         FUNC_END aeabi_dcmpun
1252         FUNC_END unorddf2
1253
1254 #endif /* L_unorddf2 */
1255
1256 #ifdef L_arm_fixdfsi
1257
1258 ARM_FUNC_START fixdfsi
1259 ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
1260
1261         @ check exponent range.
1262         mov     r2, xh, lsl #1
1263         adds    r2, r2, #(1 << 21)
1264         bcs     2f                      @ value is INF or NAN
1265         bpl     1f                      @ value is too small
1266         mov     r3, #(0xfffffc00 + 31)
1267         subs    r2, r3, r2, asr #21
1268         bls     3f                      @ value is too large
1269
1270         @ scale value
1271         mov     r3, xh, lsl #11
1272         orr     r3, r3, #0x80000000
1273         orr     r3, r3, xl, lsr #21
1274         tst     xh, #0x80000000         @ the sign bit
1275         shift1  lsr, r0, r3, r2
1276         do_it   ne
1277         rsbne   r0, r0, #0
1278         RET
1279
1280 1:      mov     r0, #0
1281         RET
1282
1283 2:      orrs    xl, xl, xh, lsl #12
1284         bne     4f                      @ x is NAN.
1285 3:      ands    r0, xh, #0x80000000     @ the sign bit
1286         do_it   eq
1287         moveq   r0, #0x7fffffff         @ maximum signed positive si
1288         RET
1289
1290 4:      mov     r0, #0                  @ How should we convert NAN?
1291         RET
1292
1293         FUNC_END aeabi_d2iz
1294         FUNC_END fixdfsi
1295
1296 #endif /* L_fixdfsi */
1297
1298 #ifdef L_arm_fixunsdfsi
1299
1300 ARM_FUNC_START fixunsdfsi
1301 ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi
1302
1303         @ check exponent range.
1304         movs    r2, xh, lsl #1
1305         bcs     1f                      @ value is negative
1306         adds    r2, r2, #(1 << 21)
1307         bcs     2f                      @ value is INF or NAN
1308         bpl     1f                      @ value is too small
1309         mov     r3, #(0xfffffc00 + 31)
1310         subs    r2, r3, r2, asr #21
1311         bmi     3f                      @ value is too large
1312
1313         @ scale value
1314         mov     r3, xh, lsl #11
1315         orr     r3, r3, #0x80000000
1316         orr     r3, r3, xl, lsr #21
1317         shift1  lsr, r0, r3, r2
1318         RET
1319
1320 1:      mov     r0, #0
1321         RET
1322
1323 2:      orrs    xl, xl, xh, lsl #12
1324         bne     4f                      @ value is NAN.
1325 3:      mov     r0, #0xffffffff         @ maximum unsigned si
1326         RET
1327
1328 4:      mov     r0, #0                  @ How should we convert NAN?
1329         RET
1330
1331         FUNC_END aeabi_d2uiz
1332         FUNC_END fixunsdfsi
1333
1334 #endif /* L_fixunsdfsi */
1335
1336 #ifdef L_arm_truncdfsf2
1337
1338 ARM_FUNC_START truncdfsf2
1339 ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
1340
1341         @ check exponent range.
1342         mov     r2, xh, lsl #1
1343         subs    r3, r2, #((1023 - 127) << 21)
1344         do_it   cs, t
1345         COND(sub,s,cs)  ip, r3, #(1 << 21)
1346         COND(rsb,s,cs)  ip, ip, #(254 << 21)
1347         bls     2f                      @ value is out of range
1348
1349 1:      @ shift and round mantissa
1350         and     ip, xh, #0x80000000
1351         mov     r2, xl, lsl #3
1352         orr     xl, ip, xl, lsr #29
1353         cmp     r2, #0x80000000
1354         adc     r0, xl, r3, lsl #2
1355         do_it   eq
1356         biceq   r0, r0, #1
1357         RET
1358
1359 2:      @ either overflow or underflow
1360         tst     xh, #0x40000000
1361         bne     3f                      @ overflow
1362
1363         @ check if denormalized value is possible
1364         adds    r2, r3, #(23 << 21)
1365         do_it   lt, t
1366         andlt   r0, xh, #0x80000000     @ too small, return signed 0.
1367         RETc(lt)
1368
1369         @ denormalize value so we can resume with the code above afterwards.
1370         orr     xh, xh, #0x00100000
1371         mov     r2, r2, lsr #21
1372         rsb     r2, r2, #24
1373         rsb     ip, r2, #32
1374 #if defined(__thumb2__)
1375         lsls    r3, xl, ip
1376 #else
1377         movs    r3, xl, lsl ip
1378 #endif
1379         shift1  lsr, xl, xl, r2
1380         do_it   ne
1381         orrne   xl, xl, #1              @ fold r3 for rounding considerations. 
1382         mov     r3, xh, lsl #11
1383         mov     r3, r3, lsr #11
1384         shiftop orr xl xl r3 lsl ip ip
1385         shift1  lsr, r3, r3, r2
1386         mov     r3, r3, lsl #1
1387         b       1b
1388
1389 3:      @ chech for NAN
1390         mvns    r3, r2, asr #21
1391         bne     5f                      @ simple overflow
1392         orrs    r3, xl, xh, lsl #12
1393         do_it   ne, tt
1394         movne   r0, #0x7f000000
1395         orrne   r0, r0, #0x00c00000
1396         RETc(ne)                        @ return NAN
1397
1398 5:      @ return INF with sign
1399         and     r0, xh, #0x80000000
1400         orr     r0, r0, #0x7f000000
1401         orr     r0, r0, #0x00800000
1402         RET
1403
1404         FUNC_END aeabi_d2f
1405         FUNC_END truncdfsf2
1406
1407 #endif /* L_truncdfsf2 */