OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [arm/] [ieee754-sf.S] - Blame information for rev 856

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

Line No. Rev Author Line
1 38 julius
/* ieee754-sf.S single-precision floating point support for ARM
2
 
3
   Copyright (C) 2003, 2004, 2005  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 2, or (at your option) any
9
   later version.
10
 
11
   In addition to the permissions in the GNU General Public License, the
12
   Free Software Foundation gives you unlimited permission to link the
13
   compiled version of this file into combinations with other programs,
14
   and to distribute those combinations without any restriction coming
15
   from the use of this file.  (The General Public License restrictions
16
   do apply in other respects; for example, they cover modification of
17
   the file, and distribution when not linked into a combine
18
   executable.)
19
 
20
   This file is distributed in the hope that it will be useful, but
21
   WITHOUT ANY WARRANTY; without even the implied warranty of
22
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23
   General Public License for more details.
24
 
25
   You should have received a copy of the GNU General Public License
26
   along with this program; see the file COPYING.  If not, write to
27
   the Free Software Foundation, 51 Franklin Street, Fifth Floor,
28
   Boston, MA 02110-1301, USA.  */
29
 
30
/*
31
 * Notes:
32
 *
33
 * The goal of this code is to be as fast as possible.  This is
34
 * not meant to be easy to understand for the casual reader.
35
 *
36
 * Only the default rounding mode is intended for best performances.
37
 * Exceptions aren't supported yet, but that can be added quite easily
38
 * if necessary without impacting performances.
39
 */
40
 
41
#ifdef L_negsf2
42
 
43
ARM_FUNC_START negsf2
44
ARM_FUNC_ALIAS aeabi_fneg negsf2
45
 
46
        eor     r0, r0, #0x80000000     @ flip sign bit
47
        RET
48
 
49
        FUNC_END aeabi_fneg
50
        FUNC_END negsf2
51
 
52
#endif
53
 
54
#ifdef L_addsubsf3
55
 
56
ARM_FUNC_START aeabi_frsub
57
 
58
        eor     r0, r0, #0x80000000     @ flip sign bit of first arg
59
        b       1f
60
 
61
ARM_FUNC_START subsf3
62
ARM_FUNC_ALIAS aeabi_fsub subsf3
63
 
64
        eor     r1, r1, #0x80000000     @ flip sign bit of second arg
65
#if defined(__INTERWORKING_STUBS__)
66
        b       1f                      @ Skip Thumb-code prologue
67
#endif
68
 
69
ARM_FUNC_START addsf3
70
ARM_FUNC_ALIAS aeabi_fadd addsf3
71
 
72
1:      @ Look for zeroes, equal values, INF, or NAN.
73
        movs    r2, r0, lsl #1
74
        movnes  r3, r1, lsl #1
75
        teqne   r2, r3
76
        mvnnes  ip, r2, asr #24
77
        mvnnes  ip, r3, asr #24
78
        beq     LSYM(Lad_s)
79
 
80
        @ Compute exponent difference.  Make largest exponent in r2,
81
        @ corresponding arg in r0, and positive exponent difference in r3.
82
        mov     r2, r2, lsr #24
83
        rsbs    r3, r2, r3, lsr #24
84
        addgt   r2, r2, r3
85
        eorgt   r1, r0, r1
86
        eorgt   r0, r1, r0
87
        eorgt   r1, r0, r1
88
        rsblt   r3, r3, #0
89
 
90
        @ If exponent difference is too large, return largest argument
91
        @ already in r0.  We need up to 25 bit to handle proper rounding
92
        @ of 0x1p25 - 1.1.
93
        cmp     r3, #25
94
        RETc(hi)
95
 
96
        @ Convert mantissa to signed integer.
97
        tst     r0, #0x80000000
98
        orr     r0, r0, #0x00800000
99
        bic     r0, r0, #0xff000000
100
        rsbne   r0, r0, #0
101
        tst     r1, #0x80000000
102
        orr     r1, r1, #0x00800000
103
        bic     r1, r1, #0xff000000
104
        rsbne   r1, r1, #0
105
 
106
        @ If exponent == difference, one or both args were denormalized.
107
        @ Since this is not common case, rescale them off line.
108
        teq     r2, r3
109
        beq     LSYM(Lad_d)
110
LSYM(Lad_x):
111
 
112
        @ Compensate for the exponent overlapping the mantissa MSB added later
113
        sub     r2, r2, #1
114
 
115
        @ Shift and add second arg to first arg in r0.
116
        @ Keep leftover bits into r1.
117
        adds    r0, r0, r1, asr r3
118
        rsb     r3, r3, #32
119
        mov     r1, r1, lsl r3
120
 
121
        @ Keep absolute value in r0-r1, sign in r3 (the n bit was set above)
122
        and     r3, r0, #0x80000000
123
        bpl     LSYM(Lad_p)
124
        rsbs    r1, r1, #0
125
        rsc     r0, r0, #0
126
 
127
        @ Determine how to normalize the result.
128
LSYM(Lad_p):
129
        cmp     r0, #0x00800000
130
        bcc     LSYM(Lad_a)
131
        cmp     r0, #0x01000000
132
        bcc     LSYM(Lad_e)
133
 
134
        @ Result needs to be shifted right.
135
        movs    r0, r0, lsr #1
136
        mov     r1, r1, rrx
137
        add     r2, r2, #1
138
 
139
        @ Make sure we did not bust our exponent.
140
        cmp     r2, #254
141
        bhs     LSYM(Lad_o)
142
 
143
        @ Our result is now properly aligned into r0, remaining bits in r1.
144
        @ Pack final result together.
145
        @ Round with MSB of r1. If halfway between two numbers, round towards
146
        @ LSB of r0 = 0.
147
LSYM(Lad_e):
148
        cmp     r1, #0x80000000
149
        adc     r0, r0, r2, lsl #23
150
        biceq   r0, r0, #1
151
        orr     r0, r0, r3
152
        RET
153
 
154
        @ Result must be shifted left and exponent adjusted.
155
LSYM(Lad_a):
156
        movs    r1, r1, lsl #1
157
        adc     r0, r0, r0
158
        tst     r0, #0x00800000
159
        sub     r2, r2, #1
160
        bne     LSYM(Lad_e)
161
 
162
        @ No rounding necessary since r1 will always be 0 at this point.
163
LSYM(Lad_l):
164
 
165
#if __ARM_ARCH__ < 5
166
 
167
        movs    ip, r0, lsr #12
168
        moveq   r0, r0, lsl #12
169
        subeq   r2, r2, #12
170
        tst     r0, #0x00ff0000
171
        moveq   r0, r0, lsl #8
172
        subeq   r2, r2, #8
173
        tst     r0, #0x00f00000
174
        moveq   r0, r0, lsl #4
175
        subeq   r2, r2, #4
176
        tst     r0, #0x00c00000
177
        moveq   r0, r0, lsl #2
178
        subeq   r2, r2, #2
179
        cmp     r0, #0x00800000
180
        movcc   r0, r0, lsl #1
181
        sbcs    r2, r2, #0
182
 
183
#else
184
 
185
        clz     ip, r0
186
        sub     ip, ip, #8
187
        subs    r2, r2, ip
188
        mov     r0, r0, lsl ip
189
 
190
#endif
191
 
192
        @ Final result with sign
193
        @ If exponent negative, denormalize result.
194
        addge   r0, r0, r2, lsl #23
195
        rsblt   r2, r2, #0
196
        orrge   r0, r0, r3
197
        orrlt   r0, r3, r0, lsr r2
198
        RET
199
 
200
        @ Fixup and adjust bit position for denormalized arguments.
201
        @ Note that r2 must not remain equal to 0.
202
LSYM(Lad_d):
203
        teq     r2, #0
204
        eor     r1, r1, #0x00800000
205
        eoreq   r0, r0, #0x00800000
206
        addeq   r2, r2, #1
207
        subne   r3, r3, #1
208
        b       LSYM(Lad_x)
209
 
210
LSYM(Lad_s):
211
        mov     r3, r1, lsl #1
212
 
213
        mvns    ip, r2, asr #24
214
        mvnnes  ip, r3, asr #24
215
        beq     LSYM(Lad_i)
216
 
217
        teq     r2, r3
218
        beq     1f
219
 
220
        @ Result is x + 0.0 = x or 0.0 + y = y.
221
        teq     r2, #0
222
        moveq   r0, r1
223
        RET
224
 
225
1:      teq     r0, r1
226
 
227
        @ Result is x - x = 0.
228
        movne   r0, #0
229
        RETc(ne)
230
 
231
        @ Result is x + x = 2x.
232
        tst     r2, #0xff000000
233
        bne     2f
234
        movs    r0, r0, lsl #1
235
        orrcs   r0, r0, #0x80000000
236
        RET
237
2:      adds    r2, r2, #(2 << 24)
238
        addcc   r0, r0, #(1 << 23)
239
        RETc(cc)
240
        and     r3, r0, #0x80000000
241
 
242
        @ Overflow: return INF.
243
LSYM(Lad_o):
244
        orr     r0, r3, #0x7f000000
245
        orr     r0, r0, #0x00800000
246
        RET
247
 
248
        @ At least one of r0/r1 is INF/NAN.
249
        @   if r0 != INF/NAN: return r1 (which is INF/NAN)
250
        @   if r1 != INF/NAN: return r0 (which is INF/NAN)
251
        @   if r0 or r1 is NAN: return NAN
252
        @   if opposite sign: return NAN
253
        @   otherwise return r0 (which is INF or -INF)
254
LSYM(Lad_i):
255
        mvns    r2, r2, asr #24
256
        movne   r0, r1
257
        mvneqs  r3, r3, asr #24
258
        movne   r1, r0
259
        movs    r2, r0, lsl #9
260
        moveqs  r3, r1, lsl #9
261
        teqeq   r0, r1
262
        orrne   r0, r0, #0x00400000     @ quiet NAN
263
        RET
264
 
265
        FUNC_END aeabi_frsub
266
        FUNC_END aeabi_fadd
267
        FUNC_END addsf3
268
        FUNC_END aeabi_fsub
269
        FUNC_END subsf3
270
 
271
ARM_FUNC_START floatunsisf
272
ARM_FUNC_ALIAS aeabi_ui2f floatunsisf
273
 
274
        mov     r3, #0
275
        b       1f
276
 
277
ARM_FUNC_START floatsisf
278
ARM_FUNC_ALIAS aeabi_i2f floatsisf
279
 
280
        ands    r3, r0, #0x80000000
281
        rsbmi   r0, r0, #0
282
 
283
1:      movs    ip, r0
284
        RETc(eq)
285
 
286
        @ Add initial exponent to sign
287
        orr     r3, r3, #((127 + 23) << 23)
288
 
289
        .ifnc   ah, r0
290
        mov     ah, r0
291
        .endif
292
        mov     al, #0
293
        b       2f
294
 
295
        FUNC_END aeabi_i2f
296
        FUNC_END floatsisf
297
        FUNC_END aeabi_ui2f
298
        FUNC_END floatunsisf
299
 
300
ARM_FUNC_START floatundisf
301
ARM_FUNC_ALIAS aeabi_ul2f floatundisf
302
 
303
        orrs    r2, r0, r1
304
#if !defined (__VFP_FP__) && !defined(__SOFTFP__)
305
        mvfeqs  f0, #0.0
306
#endif
307
        RETc(eq)
308
 
309
        mov     r3, #0
310
        b       1f
311
 
312
ARM_FUNC_START floatdisf
313
ARM_FUNC_ALIAS aeabi_l2f floatdisf
314
 
315
        orrs    r2, r0, r1
316
#if !defined (__VFP_FP__) && !defined(__SOFTFP__)
317
        mvfeqs  f0, #0.0
318
#endif
319
        RETc(eq)
320
 
321
        ands    r3, ah, #0x80000000     @ sign bit in r3
322
        bpl     1f
323
        rsbs    al, al, #0
324
        rsc     ah, ah, #0
325
1:
326
#if !defined (__VFP_FP__) && !defined(__SOFTFP__)
327
        @ For hard FPA code we want to return via the tail below so that
328
        @ we can return the result in f0 as well as in r0 for backwards
329
        @ compatibility.
330
        str     lr, [sp, #-8]!
331
        adr     lr, LSYM(f0_ret)
332
#endif
333
 
334
        movs    ip, ah
335
        moveq   ip, al
336
        moveq   ah, al
337
        moveq   al, #0
338
 
339
        @ Add initial exponent to sign
340
        orr     r3, r3, #((127 + 23 + 32) << 23)
341
        subeq   r3, r3, #(32 << 23)
342
2:      sub     r3, r3, #(1 << 23)
343
 
344
#if __ARM_ARCH__ < 5
345
 
346
        mov     r2, #23
347
        cmp     ip, #(1 << 16)
348
        movhs   ip, ip, lsr #16
349
        subhs   r2, r2, #16
350
        cmp     ip, #(1 << 8)
351
        movhs   ip, ip, lsr #8
352
        subhs   r2, r2, #8
353
        cmp     ip, #(1 << 4)
354
        movhs   ip, ip, lsr #4
355
        subhs   r2, r2, #4
356
        cmp     ip, #(1 << 2)
357
        subhs   r2, r2, #2
358
        sublo   r2, r2, ip, lsr #1
359
        subs    r2, r2, ip, lsr #3
360
 
361
#else
362
 
363
        clz     r2, ip
364
        subs    r2, r2, #8
365
 
366
#endif
367
 
368
        sub     r3, r3, r2, lsl #23
369
        blt     3f
370
 
371
        add     r3, r3, ah, lsl r2
372
        mov     ip, al, lsl r2
373
        rsb     r2, r2, #32
374
        cmp     ip, #0x80000000
375
        adc     r0, r3, al, lsr r2
376
        biceq   r0, r0, #1
377
        RET
378
 
379
3:      add     r2, r2, #32
380
        mov     ip, ah, lsl r2
381
        rsb     r2, r2, #32
382
        orrs    al, al, ip, lsl #1
383
        adc     r0, r3, ah, lsr r2
384
        biceq   r0, r0, ip, lsr #31
385
        RET
386
 
387
#if !defined (__VFP_FP__) && !defined(__SOFTFP__)
388
 
389
LSYM(f0_ret):
390
        str     r0, [sp, #-4]!
391
        ldfs    f0, [sp], #4
392
        RETLDM
393
 
394
#endif
395
 
396
        FUNC_END floatdisf
397
        FUNC_END aeabi_l2f
398
        FUNC_END floatundisf
399
        FUNC_END aeabi_ul2f
400
 
401
#endif /* L_addsubsf3 */
402
 
403
#ifdef L_muldivsf3
404
 
405
ARM_FUNC_START mulsf3
406
ARM_FUNC_ALIAS aeabi_fmul mulsf3
407
 
408
        @ Mask out exponents, trap any zero/denormal/INF/NAN.
409
        mov     ip, #0xff
410
        ands    r2, ip, r0, lsr #23
411
        andnes  r3, ip, r1, lsr #23
412
        teqne   r2, ip
413
        teqne   r3, ip
414
        beq     LSYM(Lml_s)
415
LSYM(Lml_x):
416
 
417
        @ Add exponents together
418
        add     r2, r2, r3
419
 
420
        @ Determine final sign.
421
        eor     ip, r0, r1
422
 
423
        @ Convert mantissa to unsigned integer.
424
        @ If power of two, branch to a separate path.
425
        @ Make up for final alignment.
426
        movs    r0, r0, lsl #9
427
        movnes  r1, r1, lsl #9
428
        beq     LSYM(Lml_1)
429
        mov     r3, #0x08000000
430
        orr     r0, r3, r0, lsr #5
431
        orr     r1, r3, r1, lsr #5
432
 
433
#if __ARM_ARCH__ < 4
434
 
435
        @ Put sign bit in r3, which will be restored into r0 later.
436
        and     r3, ip, #0x80000000
437
 
438
        @ Well, no way to make it shorter without the umull instruction.
439
        stmfd   sp!, {r3, r4, r5}
440
        mov     r4, r0, lsr #16
441
        mov     r5, r1, lsr #16
442
        bic     r0, r0, r4, lsl #16
443
        bic     r1, r1, r5, lsl #16
444
        mul     ip, r4, r5
445
        mul     r3, r0, r1
446
        mul     r0, r5, r0
447
        mla     r0, r4, r1, r0
448
        adds    r3, r3, r0, lsl #16
449
        adc     r1, ip, r0, lsr #16
450
        ldmfd   sp!, {r0, r4, r5}
451
 
452
#else
453
 
454
        @ The actual multiplication.
455
        umull   r3, r1, r0, r1
456
 
457
        @ Put final sign in r0.
458
        and     r0, ip, #0x80000000
459
 
460
#endif
461
 
462
        @ Adjust result upon the MSB position.
463
        cmp     r1, #(1 << 23)
464
        movcc   r1, r1, lsl #1
465
        orrcc   r1, r1, r3, lsr #31
466
        movcc   r3, r3, lsl #1
467
 
468
        @ Add sign to result.
469
        orr     r0, r0, r1
470
 
471
        @ Apply exponent bias, check for under/overflow.
472
        sbc     r2, r2, #127
473
        cmp     r2, #(254 - 1)
474
        bhi     LSYM(Lml_u)
475
 
476
        @ Round the result, merge final exponent.
477
        cmp     r3, #0x80000000
478
        adc     r0, r0, r2, lsl #23
479
        biceq   r0, r0, #1
480
        RET
481
 
482
        @ Multiplication by 0x1p*: let''s shortcut a lot of code.
483
LSYM(Lml_1):
484
        teq     r0, #0
485
        and     ip, ip, #0x80000000
486
        moveq   r1, r1, lsl #9
487
        orr     r0, ip, r0, lsr #9
488
        orr     r0, r0, r1, lsr #9
489
        subs    r2, r2, #127
490
        rsbgts  r3, r2, #255
491
        orrgt   r0, r0, r2, lsl #23
492
        RETc(gt)
493
 
494
        @ Under/overflow: fix things up for the code below.
495
        orr     r0, r0, #0x00800000
496
        mov     r3, #0
497
        subs    r2, r2, #1
498
 
499
LSYM(Lml_u):
500
        @ Overflow?
501
        bgt     LSYM(Lml_o)
502
 
503
        @ Check if denormalized result is possible, otherwise return signed 0.
504
        cmn     r2, #(24 + 1)
505
        bicle   r0, r0, #0x7fffffff
506
        RETc(le)
507
 
508
        @ Shift value right, round, etc.
509
        rsb     r2, r2, #0
510
        movs    r1, r0, lsl #1
511
        mov     r1, r1, lsr r2
512
        rsb     r2, r2, #32
513
        mov     ip, r0, lsl r2
514
        movs    r0, r1, rrx
515
        adc     r0, r0, #0
516
        orrs    r3, r3, ip, lsl #1
517
        biceq   r0, r0, ip, lsr #31
518
        RET
519
 
520
        @ One or both arguments are denormalized.
521
        @ Scale them leftwards and preserve sign bit.
522
LSYM(Lml_d):
523
        teq     r2, #0
524
        and     ip, r0, #0x80000000
525
1:      moveq   r0, r0, lsl #1
526
        tsteq   r0, #0x00800000
527
        subeq   r2, r2, #1
528
        beq     1b
529
        orr     r0, r0, ip
530
        teq     r3, #0
531
        and     ip, r1, #0x80000000
532
2:      moveq   r1, r1, lsl #1
533
        tsteq   r1, #0x00800000
534
        subeq   r3, r3, #1
535
        beq     2b
536
        orr     r1, r1, ip
537
        b       LSYM(Lml_x)
538
 
539
LSYM(Lml_s):
540
        @ Isolate the INF and NAN cases away
541
        and     r3, ip, r1, lsr #23
542
        teq     r2, ip
543
        teqne   r3, ip
544
        beq     1f
545
 
546
        @ Here, one or more arguments are either denormalized or zero.
547
        bics    ip, r0, #0x80000000
548
        bicnes  ip, r1, #0x80000000
549
        bne     LSYM(Lml_d)
550
 
551
        @ Result is 0, but determine sign anyway.
552
LSYM(Lml_z):
553
        eor     r0, r0, r1
554
        bic     r0, r0, #0x7fffffff
555
        RET
556
 
557
1:      @ One or both args are INF or NAN.
558
        teq     r0, #0x0
559
        teqne   r0, #0x80000000
560
        moveq   r0, r1
561
        teqne   r1, #0x0
562
        teqne   r1, #0x80000000
563
        beq     LSYM(Lml_n)             @ 0 * INF or INF * 0 -> NAN
564
        teq     r2, ip
565
        bne     1f
566
        movs    r2, r0, lsl #9
567
        bne     LSYM(Lml_n)             @ NAN *  -> NAN
568
1:      teq     r3, ip
569
        bne     LSYM(Lml_i)
570
        movs    r3, r1, lsl #9
571
        movne   r0, r1
572
        bne     LSYM(Lml_n)             @  * NAN -> NAN
573
 
574
        @ Result is INF, but we need to determine its sign.
575
LSYM(Lml_i):
576
        eor     r0, r0, r1
577
 
578
        @ Overflow: return INF (sign already in r0).
579
LSYM(Lml_o):
580
        and     r0, r0, #0x80000000
581
        orr     r0, r0, #0x7f000000
582
        orr     r0, r0, #0x00800000
583
        RET
584
 
585
        @ Return a quiet NAN.
586
LSYM(Lml_n):
587
        orr     r0, r0, #0x7f000000
588
        orr     r0, r0, #0x00c00000
589
        RET
590
 
591
        FUNC_END aeabi_fmul
592
        FUNC_END mulsf3
593
 
594
ARM_FUNC_START divsf3
595
ARM_FUNC_ALIAS aeabi_fdiv divsf3
596
 
597
        @ Mask out exponents, trap any zero/denormal/INF/NAN.
598
        mov     ip, #0xff
599
        ands    r2, ip, r0, lsr #23
600
        andnes  r3, ip, r1, lsr #23
601
        teqne   r2, ip
602
        teqne   r3, ip
603
        beq     LSYM(Ldv_s)
604
LSYM(Ldv_x):
605
 
606
        @ Substract divisor exponent from dividend''s
607
        sub     r2, r2, r3
608
 
609
        @ Preserve final sign into ip.
610
        eor     ip, r0, r1
611
 
612
        @ Convert mantissa to unsigned integer.
613
        @ Dividend -> r3, divisor -> r1.
614
        movs    r1, r1, lsl #9
615
        mov     r0, r0, lsl #9
616
        beq     LSYM(Ldv_1)
617
        mov     r3, #0x10000000
618
        orr     r1, r3, r1, lsr #4
619
        orr     r3, r3, r0, lsr #4
620
 
621
        @ Initialize r0 (result) with final sign bit.
622
        and     r0, ip, #0x80000000
623
 
624
        @ Ensure result will land to known bit position.
625
        @ Apply exponent bias accordingly.
626
        cmp     r3, r1
627
        movcc   r3, r3, lsl #1
628
        adc     r2, r2, #(127 - 2)
629
 
630
        @ The actual division loop.
631
        mov     ip, #0x00800000
632
1:      cmp     r3, r1
633
        subcs   r3, r3, r1
634
        orrcs   r0, r0, ip
635
        cmp     r3, r1, lsr #1
636
        subcs   r3, r3, r1, lsr #1
637
        orrcs   r0, r0, ip, lsr #1
638
        cmp     r3, r1, lsr #2
639
        subcs   r3, r3, r1, lsr #2
640
        orrcs   r0, r0, ip, lsr #2
641
        cmp     r3, r1, lsr #3
642
        subcs   r3, r3, r1, lsr #3
643
        orrcs   r0, r0, ip, lsr #3
644
        movs    r3, r3, lsl #4
645
        movnes  ip, ip, lsr #4
646
        bne     1b
647
 
648
        @ Check exponent for under/overflow.
649
        cmp     r2, #(254 - 1)
650
        bhi     LSYM(Lml_u)
651
 
652
        @ Round the result, merge final exponent.
653
        cmp     r3, r1
654
        adc     r0, r0, r2, lsl #23
655
        biceq   r0, r0, #1
656
        RET
657
 
658
        @ Division by 0x1p*: let''s shortcut a lot of code.
659
LSYM(Ldv_1):
660
        and     ip, ip, #0x80000000
661
        orr     r0, ip, r0, lsr #9
662
        adds    r2, r2, #127
663
        rsbgts  r3, r2, #255
664
        orrgt   r0, r0, r2, lsl #23
665
        RETc(gt)
666
 
667
        orr     r0, r0, #0x00800000
668
        mov     r3, #0
669
        subs    r2, r2, #1
670
        b       LSYM(Lml_u)
671
 
672
        @ One or both arguments are denormalized.
673
        @ Scale them leftwards and preserve sign bit.
674
LSYM(Ldv_d):
675
        teq     r2, #0
676
        and     ip, r0, #0x80000000
677
1:      moveq   r0, r0, lsl #1
678
        tsteq   r0, #0x00800000
679
        subeq   r2, r2, #1
680
        beq     1b
681
        orr     r0, r0, ip
682
        teq     r3, #0
683
        and     ip, r1, #0x80000000
684
2:      moveq   r1, r1, lsl #1
685
        tsteq   r1, #0x00800000
686
        subeq   r3, r3, #1
687
        beq     2b
688
        orr     r1, r1, ip
689
        b       LSYM(Ldv_x)
690
 
691
        @ One or both arguments are either INF, NAN, zero or denormalized.
692
LSYM(Ldv_s):
693
        and     r3, ip, r1, lsr #23
694
        teq     r2, ip
695
        bne     1f
696
        movs    r2, r0, lsl #9
697
        bne     LSYM(Lml_n)             @ NAN /  -> NAN
698
        teq     r3, ip
699
        bne     LSYM(Lml_i)             @ INF /  -> INF
700
        mov     r0, r1
701
        b       LSYM(Lml_n)             @ INF / (INF or NAN) -> NAN
702
1:      teq     r3, ip
703
        bne     2f
704
        movs    r3, r1, lsl #9
705
        beq     LSYM(Lml_z)             @  / INF -> 0
706
        mov     r0, r1
707
        b       LSYM(Lml_n)             @  / NAN -> NAN
708
2:      @ If both are nonzero, we need to normalize and resume above.
709
        bics    ip, r0, #0x80000000
710
        bicnes  ip, r1, #0x80000000
711
        bne     LSYM(Ldv_d)
712
        @ One or both arguments are zero.
713
        bics    r2, r0, #0x80000000
714
        bne     LSYM(Lml_i)             @  / 0 -> INF
715
        bics    r3, r1, #0x80000000
716
        bne     LSYM(Lml_z)             @ 0 /  -> 0
717
        b       LSYM(Lml_n)             @ 0 / 0 -> NAN
718
 
719
        FUNC_END aeabi_fdiv
720
        FUNC_END divsf3
721
 
722
#endif /* L_muldivsf3 */
723
 
724
#ifdef L_cmpsf2
725
 
726
        @ The return value in r0 is
727
        @
728
        @   0  if the operands are equal
729
        @   1  if the first operand is greater than the second, or
730
        @      the operands are unordered and the operation is
731
        @      CMP, LT, LE, NE, or EQ.
732
        @   -1 if the first operand is less than the second, or
733
        @      the operands are unordered and the operation is GT
734
        @      or GE.
735
        @
736
        @ The Z flag will be set iff the operands are equal.
737
        @
738
        @ The following registers are clobbered by this function:
739
        @   ip, r0, r1, r2, r3
740
 
741
ARM_FUNC_START gtsf2
742
ARM_FUNC_ALIAS gesf2 gtsf2
743
        mov     ip, #-1
744
        b       1f
745
 
746
ARM_FUNC_START ltsf2
747
ARM_FUNC_ALIAS lesf2 ltsf2
748
        mov     ip, #1
749
        b       1f
750
 
751
ARM_FUNC_START cmpsf2
752
ARM_FUNC_ALIAS nesf2 cmpsf2
753
ARM_FUNC_ALIAS eqsf2 cmpsf2
754
        mov     ip, #1                  @ how should we specify unordered here?
755
 
756
1:      str     ip, [sp, #-4]
757
 
758
        @ Trap any INF/NAN first.
759
        mov     r2, r0, lsl #1
760
        mov     r3, r1, lsl #1
761
        mvns    ip, r2, asr #24
762
        mvnnes  ip, r3, asr #24
763
        beq     3f
764
 
765
        @ Compare values.
766
        @ Note that 0.0 is equal to -0.0.
767
2:      orrs    ip, r2, r3, lsr #1      @ test if both are 0, clear C flag
768
        teqne   r0, r1                  @ if not 0 compare sign
769
        subpls  r0, r2, r3              @ if same sign compare values, set r0
770
 
771
        @ Result:
772
        movhi   r0, r1, asr #31
773
        mvnlo   r0, r1, asr #31
774
        orrne   r0, r0, #1
775
        RET
776
 
777
        @ Look for a NAN.
778
3:      mvns    ip, r2, asr #24
779
        bne     4f
780
        movs    ip, r0, lsl #9
781
        bne     5f                      @ r0 is NAN
782
4:      mvns    ip, r3, asr #24
783
        bne     2b
784
        movs    ip, r1, lsl #9
785
        beq     2b                      @ r1 is not NAN
786
5:      ldr     r0, [sp, #-4]           @ return unordered code.
787
        RET
788
 
789
        FUNC_END gesf2
790
        FUNC_END gtsf2
791
        FUNC_END lesf2
792
        FUNC_END ltsf2
793
        FUNC_END nesf2
794
        FUNC_END eqsf2
795
        FUNC_END cmpsf2
796
 
797
ARM_FUNC_START aeabi_cfrcmple
798
 
799
        mov     ip, r0
800
        mov     r0, r1
801
        mov     r1, ip
802
        b       6f
803
 
804
ARM_FUNC_START aeabi_cfcmpeq
805
ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq
806
 
807
        @ The status-returning routines are required to preserve all
808
        @ registers except ip, lr, and cpsr.
809
6:      stmfd   sp!, {r0, r1, r2, r3, lr}
810
        ARM_CALL cmpsf2
811
        @ Set the Z flag correctly, and the C flag unconditionally.
812
        cmp      r0, #0
813
        @ Clear the C flag if the return value was -1, indicating
814
        @ that the first operand was smaller than the second.
815
        cmnmi    r0, #0
816
        RETLDM  "r0, r1, r2, r3"
817
 
818
        FUNC_END aeabi_cfcmple
819
        FUNC_END aeabi_cfcmpeq
820
        FUNC_END aeabi_cfrcmple
821
 
822
ARM_FUNC_START  aeabi_fcmpeq
823
 
824
        str     lr, [sp, #-8]!
825
        ARM_CALL aeabi_cfcmple
826
        moveq   r0, #1  @ Equal to.
827
        movne   r0, #0  @ Less than, greater than, or unordered.
828
        RETLDM
829
 
830
        FUNC_END aeabi_fcmpeq
831
 
832
ARM_FUNC_START  aeabi_fcmplt
833
 
834
        str     lr, [sp, #-8]!
835
        ARM_CALL aeabi_cfcmple
836
        movcc   r0, #1  @ Less than.
837
        movcs   r0, #0  @ Equal to, greater than, or unordered.
838
        RETLDM
839
 
840
        FUNC_END aeabi_fcmplt
841
 
842
ARM_FUNC_START  aeabi_fcmple
843
 
844
        str     lr, [sp, #-8]!
845
        ARM_CALL aeabi_cfcmple
846
        movls   r0, #1  @ Less than or equal to.
847
        movhi   r0, #0  @ Greater than or unordered.
848
        RETLDM
849
 
850
        FUNC_END aeabi_fcmple
851
 
852
ARM_FUNC_START  aeabi_fcmpge
853
 
854
        str     lr, [sp, #-8]!
855
        ARM_CALL aeabi_cfrcmple
856
        movls   r0, #1  @ Operand 2 is less than or equal to operand 1.
857
        movhi   r0, #0  @ Operand 2 greater than operand 1, or unordered.
858
        RETLDM
859
 
860
        FUNC_END aeabi_fcmpge
861
 
862
ARM_FUNC_START  aeabi_fcmpgt
863
 
864
        str     lr, [sp, #-8]!
865
        ARM_CALL aeabi_cfrcmple
866
        movcc   r0, #1  @ Operand 2 is less than operand 1.
867
        movcs   r0, #0  @ Operand 2 is greater than or equal to operand 1,
868
                        @ or they are unordered.
869
        RETLDM
870
 
871
        FUNC_END aeabi_fcmpgt
872
 
873
#endif /* L_cmpsf2 */
874
 
875
#ifdef L_unordsf2
876
 
877
ARM_FUNC_START unordsf2
878
ARM_FUNC_ALIAS aeabi_fcmpun unordsf2
879
 
880
        mov     r2, r0, lsl #1
881
        mov     r3, r1, lsl #1
882
        mvns    ip, r2, asr #24
883
        bne     1f
884
        movs    ip, r0, lsl #9
885
        bne     3f                      @ r0 is NAN
886
1:      mvns    ip, r3, asr #24
887
        bne     2f
888
        movs    ip, r1, lsl #9
889
        bne     3f                      @ r1 is NAN
890
2:      mov     r0, #0                  @ arguments are ordered.
891
        RET
892
3:      mov     r0, #1                  @ arguments are unordered.
893
        RET
894
 
895
        FUNC_END aeabi_fcmpun
896
        FUNC_END unordsf2
897
 
898
#endif /* L_unordsf2 */
899
 
900
#ifdef L_fixsfsi
901
 
902
ARM_FUNC_START fixsfsi
903
ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
904
 
905
        @ check exponent range.
906
        mov     r2, r0, lsl #1
907
        cmp     r2, #(127 << 24)
908
        bcc     1f                      @ value is too small
909
        mov     r3, #(127 + 31)
910
        subs    r2, r3, r2, lsr #24
911
        bls     2f                      @ value is too large
912
 
913
        @ scale value
914
        mov     r3, r0, lsl #8
915
        orr     r3, r3, #0x80000000
916
        tst     r0, #0x80000000         @ the sign bit
917
        mov     r0, r3, lsr r2
918
        rsbne   r0, r0, #0
919
        RET
920
 
921
1:      mov     r0, #0
922
        RET
923
 
924
2:      cmp     r2, #(127 + 31 - 0xff)
925
        bne     3f
926
        movs    r2, r0, lsl #9
927
        bne     4f                      @ r0 is NAN.
928
3:      ands    r0, r0, #0x80000000     @ the sign bit
929
        moveq   r0, #0x7fffffff         @ the maximum signed positive si
930
        RET
931
 
932
4:      mov     r0, #0                  @ What should we convert NAN to?
933
        RET
934
 
935
        FUNC_END aeabi_f2iz
936
        FUNC_END fixsfsi
937
 
938
#endif /* L_fixsfsi */
939
 
940
#ifdef L_fixunssfsi
941
 
942
ARM_FUNC_START fixunssfsi
943
ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi
944
 
945
        @ check exponent range.
946
        movs    r2, r0, lsl #1
947
        bcs     1f                      @ value is negative
948
        cmp     r2, #(127 << 24)
949
        bcc     1f                      @ value is too small
950
        mov     r3, #(127 + 31)
951
        subs    r2, r3, r2, lsr #24
952
        bmi     2f                      @ value is too large
953
 
954
        @ scale the value
955
        mov     r3, r0, lsl #8
956
        orr     r3, r3, #0x80000000
957
        mov     r0, r3, lsr r2
958
        RET
959
 
960
1:      mov     r0, #0
961
        RET
962
 
963
2:      cmp     r2, #(127 + 31 - 0xff)
964
        bne     3f
965
        movs    r2, r0, lsl #9
966
        bne     4f                      @ r0 is NAN.
967
3:      mov     r0, #0xffffffff         @ maximum unsigned si
968
        RET
969
 
970
4:      mov     r0, #0                  @ What should we convert NAN to?
971
        RET
972
 
973
        FUNC_END aeabi_f2uiz
974
        FUNC_END fixunssfsi
975
 
976
#endif /* L_fixunssfsi */

powered by: WebSVN 2.1.0

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