~ubuntu-branches/ubuntu/raring/avr-libc/raring-proposed

« back to all changes in this revision

Viewing changes to libm/fplib/lround.S

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2008-08-10 09:59:16 UTC
  • mfrom: (1.2.1 upstream) (8 intrepid)
  • mto: (4.1.7 sid)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20080810095916-7ku06pjsfia3hz16
Added build-depends on texlive-extra-utils (closes: #493454)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2007  Dmitry Xmelkov
 
2
   All rights reserved.
 
3
 
 
4
   Redistribution and use in source and binary forms, with or without
 
5
   modification, are permitted provided that the following conditions are met:
 
6
 
 
7
   * Redistributions of source code must retain the above copyright
 
8
     notice, this list of conditions and the following disclaimer.
 
9
   * Redistributions in binary form must reproduce the above copyright
 
10
     notice, this list of conditions and the following disclaimer in
 
11
     the documentation and/or other materials provided with the
 
12
     distribution.
 
13
   * Neither the name of the copyright holders nor the names of
 
14
     contributors may be used to endorse or promote products derived
 
15
     from this software without specific prior written permission.
 
16
 
 
17
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
18
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
19
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
20
   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
21
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
22
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
23
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
24
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
25
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
26
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
27
   POSSIBILITY OF SUCH DAMAGE. */
 
28
 
 
29
/* $Id: lround.S,v 1.2 2007/12/01 02:12:54 dmix Exp $ */
 
30
 
 
31
#include "fp32def.h"
 
32
#include "asmdef.h"
 
33
 
 
34
/* long lround (double A);
 
35
     The lround() function rounds A to the nearest integer, but rounds
 
36
     halfway cases away from zero (instead of to the nearest even integer).
 
37
     This function is similar to round() function, but it differs in
 
38
     type of return value and in that an overflow is possible.
 
39
   Return:
 
40
     The rounded long integer value. If A is infinite, NaN or an overflow
 
41
     was, this realization returns the LONG_MIN value (0x80000000).
 
42
 
 
43
   Algorithm roughly:
 
44
     - split
 
45
     - shift mantissa according to exponent
 
46
     - add 0.5 to round
 
47
     - restore the sign
 
48
 
 
49
   Objections to saturation are listen in __fixunssfsi.S file.
 
50
 */
 
51
 
 
52
ENTRY lround
 
53
        rcall   _U(__fp_splitA)
 
54
        brcs    .L_err
 
55
  ; A is finite
 
56
        subi    rA3, 126        ; exponent field of 0.5
 
57
        brlo    .L_zr           ; A is too small
 
58
  ; fabs(A) >= 0x0.800000p+00
 
59
        subi    rA3, 24
 
60
        brlo    2f              ; shtft to right and round
 
61
        breq    .L_sign         ; no shift
 
62
  ; fabs(A) >= 0x0.800000p+25
 
63
        cpi     rA3, 8
 
64
        brsh    .L_err          ; A is too big
 
65
 
 
66
  ; 0x0.800000p+25 <= fabs(A) <= 0x0.ffffffp+31  --> shift to left by 1..7
 
67
        mov     r0, rA3         ; shift counter
 
68
        clr     rA3             ; MSB
 
69
  ; rA3.2.1.0 <<= r0
 
70
1:      lsl     rA0
 
71
        rol     rA1
 
72
        rol     rA2
 
73
        rol     rA3
 
74
        dec     r0
 
75
        brne    1b
 
76
        rjmp    .L_sign
 
77
 
 
78
  ; quick shift to right by 8
 
79
5:      mov     r0, rA0         ; save for possible round
 
80
        mov     rA0, rA1
 
81
        mov     rA1, rA2
 
82
        clr     rA2
 
83
        subi    rA3, -8
 
84
        brne    2f
 
85
        lsl     r0              ; restore C
 
86
        rjmp    4f              ; and round
 
87
  ; 0x0.800000p+00 <= fabs(A) <= 0x0.ffffffp+23
 
88
  ; Shift A to right by 1 (rA3 == -1) .. 24 (rA3 == -24) positions and
 
89
  ; round.
 
90
2:      cpi     rA3, -7
 
91
        brlt    5b
 
92
  ; shift to right by 1..7 (slow)
 
93
3:      lsr     rA2
 
94
        ror     rA1
 
95
        ror     rA0             ; --> C
 
96
        inc     rA3             ; C is not changed
 
97
        brne    3b
 
98
  ; Round. Now flag C is set if fractional is >= 0.5
 
99
4:      adc     rA0, r1
 
100
        adc     rA1, r1
 
101
        adc     rA2, r1         ; rA2 was <= 0x7f, so rA3 will not changed
 
102
 
 
103
  ; restore the sign and return
 
104
.L_sign:
 
105
        brtc    6f
 
106
        com     rA3
 
107
        com     rA2
 
108
        com     rA1
 
109
        neg     rA0
 
110
        sbci    rA1, -1
 
111
        sbci    rA2, -1
 
112
        sbci    rA3, -1
 
113
6:      ret
 
114
 
 
115
.L_err: set                     ; force return 0x80000000
 
116
        rjmp    _U(__fp_szero)
 
117
 
 
118
.L_zr:  rjmp    _U(__fp_zero)   ; return 0x00000000
 
119
 
 
120
ENDFUNC