OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [arm/] [ieee754-df.S] - Blame information for rev 484

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.