~ubuntu-branches/ubuntu/intrepid/avr-libc/intrepid

« back to all changes in this revision

Viewing changes to libm/fplib/sqrt.S

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2008-04-04 17:05:32 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20080404170532-tiwwl2e2qln7ri0w
Tags: 1:1.6.2-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  -*- Mode: Asm -*-  */
2
 
 
3
1
/* Copyright (c) 2002  Michael Stumpf  <mistumpf@de.pepperl-fuchs.com>
4
 
   Copyright (c) 2006  Anatoly Sokolov <aesok@post.ru>
 
2
   Copyright (c) 2006  Dmitry Xmelkov
5
3
   All rights reserved.
6
4
 
7
 
 
8
5
   Redistribution and use in source and binary forms, with or without
9
6
   modification, are permitted provided that the following conditions are met:
10
7
 
11
8
   * Redistributions of source code must retain the above copyright
12
9
     notice, this list of conditions and the following disclaimer.
13
 
   
14
10
   * Redistributions in binary form must reproduce the above copyright
15
11
     notice, this list of conditions and the following disclaimer in
16
12
     the documentation and/or other materials provided with the
17
13
     distribution.
18
 
     
19
14
   * Neither the name of the copyright holders nor the names of
20
15
     contributors may be used to endorse or promote products derived
21
16
     from this software without specific prior written permission.
30
25
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
26
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
27
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
 
   POSSIBILITY OF SUCH DAMAGE. 
34
 
*/
35
 
 
36
 
/* $Id: sqrt.S,v 1.5.2.2 2006/01/20 20:39:28 aesok Exp $ */
37
 
 
38
 
/*
39
 
    sqrt.S is part of     FPlib V 0.3.0       ported to avr-as
40
 
    for details see readme.fplib
41
 
 
42
 
 *----------------------------------------------------------------------------------------
43
 
 *
44
 
 *      A = sqrt(A)
 
28
   POSSIBILITY OF SUCH DAMAGE. */
 
29
 
 
30
/* $Id: sqrt.S,v 1.8 2007/01/14 15:13:10 dmix Exp $ */
 
31
 
 
32
#include "fp32def.h"
 
33
#include "asmdef.h"
 
34
 
 
35
/*  double sqrt (double);
 
36
    Square root function.
45
37
 */
46
38
 
47
 
#include "gasava.inc"
48
 
#include "macros.inc"
49
 
#include "fplib.inc"
50
 
 
51
 
; Abak
52
 
#define rAbak3  rS0
53
 
#define rAbak2  rS1
54
 
#define rAbak1  rS2
55
 
#define rAbak0  rS3
56
 
 
57
 
; Bbak
58
 
#define rBbak3  rS4
59
 
#define rBbak2  rS5
60
 
#define rBbak1  rS6
61
 
#define rBbak0  rS7
62
 
 
63
 
 
64
 
        TEXT_SEG(fplib, sqrt)
65
 
        FUNCTION(sqrt)
66
 
 
67
 
GLOBAL(sqrt)
68
 
 
69
 
        SBRC    rA3, 7
70
 
        RJMP    _U(__fp_nanEDOM)        ; sign bit is set -> argument range error
71
 
 
72
 
   /* A = sign(=0):(exp+7F):[1].mant = 2^(exp)*1.mant
73
 
    *   =          (LSB(exp)+7F) + (exp>>1) + (exp>>1):[1].mant = (2^(exp>>1))^2 * 2^(LSB(exp))*1.mant
74
 
    *                                                           = 2^(exp>>1)^2 * A'
75
 
    * A' = [2^0*1.0... 2^1*1.1111111] = [1.0...4.0[
76
 
    *
77
 
    * sqrt(A) = 2^(exp>>1) * sqrt( A' )
78
 
    * sqrt(A') = [1.0...2.0[  -> result of srqt(A') has definetely exponent 7F! -> exp(X0) = 7F
79
 
    *
80
 
    * the matissa of X0 is taken as ( 0.mant >> 1 )     0.0mant
81
 
    *  plus if LSB(exp)==1 [LSB(exp-7F)==0]             0.100000
82
 
    *  plus the implicit one                            1.000000
83
 
    */
84
 
 
85
 
        TST     rA3
86
 
        BRNE    2f              ; sqrt(0) = 0
87
 
        RET
88
 
2:
89
 
        MOV     rB2, rA2        ; needed later on
90
 
 
91
 
        RCALL   _U(__fp_split_a)        ; does not return on NaN
92
 
 
93
 
        MOV     rTI0, rA3
94
 
        SUBI    rTI0, 0x7F
95
 
        ASR     rTI0            ; this is dExp!
96
 
        SUB     rA3, rTI0
97
 
        SUB     rA3, rTI0
98
 
 
99
 
        PUSH    rTI0            ; exponent offset
100
 
 
101
 
        RCALL   _U(__fp_merge)
102
 
 
103
 
        PUSH    rS0
104
 
        PUSH    rS1
105
 
        PUSH    rS2
106
 
        PUSH    rS3
107
 
        PUSH    rS4
108
 
        PUSH    rS5
109
 
        PUSH    rS6
110
 
        PUSH    rS7
111
 
 
112
 
        X_movw  rAbak0, rA0
113
 
        X_movw  rAbak2, rA2     ; Abak = A
114
 
 
115
 
        SUBI    rB2, 0x80       ; == EOR 0x80
116
 
        ROR     rB2
117
 
        CLR     rB1             ; a slightly smaller X(0) than the calculated is better
118
 
        CLR     rB0             ; and saves 2 right shifts
119
 
        ORI     rB2, 0x80       ; 
120
 
        LDI     rB3, 0x3F       ; load exponent 7F
121
 
 
 
39
FUNCTION sqrt
 
40
 
 
41
.L_nf:  brne    .L_pk           ; NaN, return as is
 
42
        brtc    .L_pk           ; sqrt(+Inf) --> +Inf
 
43
.L_nan: rjmp    _U(__fp_nan)
 
44
.L_pk:  rjmp    _U(__fp_mpack)
 
45
 
 
46
ENTRY sqrt
 
47
  ; split and check arg.
 
48
        rcall   _U(__fp_splitA)
 
49
        brcs    .L_nf           ; !isfinite(A)
 
50
        tst     rA3
 
51
        breq    .L_pk           ; return 0 with original sign
 
52
        brts    .L_nan          ; sqrt(negative) --> NaN
 
53
  ; exponent bias
 
54
        subi    rA3, 127
 
55
        sbc     rB3, rB3        ; exponent high byte
 
56
  ; normalize, if A is subnormal
 
57
        sbrs    rA2, 7
 
58
        rcall   _U(__fp_norm2)
 
59
  ; calculate result exponent
 
60
        lsr     rB3
 
61
        ror     rA3
 
62
  ; expand A mantissa to rAE.rA2.rA1.rA0
 
63
        ldi     rAE, 0
 
64
        brcc    1f              ; after 'ror rA3'
 
65
        lsl     rA0
 
66
        rol     rA1
 
67
        rol     rA2
 
68
        rol     rAE
122
69
1:
123
 
        X_movw  rA0, rAbak0
124
 
        X_movw  rA2, rAbak2     ; A = Abak
125
 
 
126
 
        X_movw  rBbak0, rB0
127
 
        X_movw  rBbak2, rB2     ; Bbak = B
128
 
 
129
 
        XCALL   __divsf3        ; FP1X = arg/xn
130
 
 
131
 
        X_movw  rB0, rBbak0
132
 
        X_movw  rB2, rBbak2     ; B = Bbak
133
 
 
134
 
        XCALL   __addsf3        ; FP1X = arg/xn + xn
135
 
 
136
 
        LDI     rPL, lo8(-1)
137
 
        LDI     rPH, hi8(-1)
138
 
        RCALL   _U(ldexp)       ; div by 2 := Xn+1
139
 
 
140
 
        X_movw  rB0, rA0
141
 
        X_movw  rB2, rA2        ; B = A
142
 
 
143
 
        CP      rBbak0, rB0
144
 
        CPC     rBbak1, rB1
145
 
        CPC     rBbak2, rB2
146
 
        CPC     rBbak3, rB3     ; cmp B to Bbak
147
 
        BRNE    1b
148
 
 
149
 
        POP     rS7
150
 
        POP     rS6
151
 
        POP     rS5
152
 
        POP     rS4
153
 
        POP     rS3
154
 
        POP     rS2
155
 
        POP     rS1
156
 
        POP     rS0
157
 
 
158
 
        POP     rB3
159
 
        
160
 
        RCALL   _U(__fp_split_a)        ; does not return on NaN
161
 
 
162
 
        ADD     rA3, rB3
163
 
 
164
 
        RJMP    _U(__fp_merge)
165
 
 
166
 
        ENDFUNC
167
 
 
168
 
 
 
70
 
 
71
#define mvb0    ZL
 
72
#define mvb1    ZH
 
73
#define mvb2    rBE
 
74
#define rem0    r16
 
75
#define rem1    r17
 
76
#define rem2    r0
 
77
#define rem3    rB3
 
78
  ; save temporary regs.
 
79
        push    rem1
 
80
        push    rem0
 
81
  ; init variables
 
82
        /* arg's mantissa:      rAE.rA2.rA1.rA0
 
83
           result:              rB2.rB2.rB0
 
84
           moving bit:          mvb2.mvb1.mvb0
 
85
           remain value:        rem3.rem2.rem1.rem0     */
 
86
        clr     r0
 
87
        X_movw  rB0, r0
 
88
        X_movw  rB2, r0
 
89
        X_movw  rem0, r0
 
90
        X_movw  mvb0, r0
 
91
        ldi     mvb2, 0x80
 
92
.Loop:
 
93
  ; rem += mvb
 
94
        add     rem0, mvb0
 
95
        adc     rem1, mvb1
 
96
        adc     rem2, mvb2
 
97
        adc     rem3, r1
 
98
  ; A -= rem
 
99
        sub     rA0, rem0
 
100
        sbc     rA1, rem1
 
101
        sbc     rA2, rem2
 
102
        sbc     rAE, rem3
 
103
        brsh    1f
 
104
  ; restore A
 
105
        add     rA0, rem0
 
106
        adc     rA1, rem1
 
107
        adc     rA2, rem2
 
108
        adc     rAE, rem3
 
109
  ; restore rem
 
110
        sub     rem0, mvb0
 
111
        sbc     rem1, mvb1
 
112
        sbc     rem2, mvb2
 
113
        sbc     rem3, r1
 
114
        rjmp    2f
 
115
  ; B += mvb
 
116
1:      add     rB0, mvb0
 
117
        adc     rB1, mvb1
 
118
        adc     rB2, mvb2
 
119
  ; rem += mvb
 
120
        add     rem0, mvb0
 
121
        adc     rem1, mvb1
 
122
        adc     rem2, mvb2
 
123
        adc     rem3, r1
 
124
  ; A <<= 1
 
125
2:      lsl     rA0
 
126
        rol     rA1
 
127
        rol     rA2
 
128
        rol     rAE
 
129
  ; while (mvb >>= 1)
 
130
        lsr     mvb2
 
131
        ror     mvb1
 
132
        ror     mvb0
 
133
        brcc    .Loop
 
134
  ; round
 
135
        cp      rem0, rA0
 
136
        cpc     rem1, rA1
 
137
        cpc     rem2, rA2
 
138
        cpc     rem3, rAE       ; C is set if rem < A
 
139
        adc     rB0, r1
 
140
        adc     rB1, r1
 
141
        adc     rB2, r1
 
142
  ; pop temporary regs.
 
143
        pop     rem0
 
144
        pop     rem1
 
145
  ; merge result and return
 
146
        X_movw  rA0, rB0
 
147
        mov     rA2, rB2
 
148
        subi    rA3, lo8(-127)          ; exponent bias
 
149
        lsl     rA2
 
150
        lsr     rA3
 
151
        ror     rA2
 
152
        ret
 
153
ENDFUNC