~ubuntu-branches/ubuntu/maverick/avr-libc/maverick

« back to all changes in this revision

Viewing changes to libm/fplib/cbrt.S

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2009-10-31 11:52:10 UTC
  • mfrom: (1.1.8 upstream) (4.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091031115210-x0mlijnegkce86fk
Tags: 1:1.6.7-1
* New upstream relese (closes: #544030)
* Added lintian overrides (closes: #553265)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2009 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: cbrt.S,v 1.1.2.2 2009/05/24 06:34:23 dmix Exp $ */
 
30
 
 
31
#include "fp32def.h"
 
32
#include "asmdef.h"
 
33
 
 
34
/* double cbrt (double)
 
35
   Cube root function.
 
36
 */
 
37
 
 
38
#define RCNT    r25
 
39
 
 
40
#define RA0     r22
 
41
#define RA1     r23
 
42
#define RA2     r24
 
43
 
 
44
#define RM0     r26
 
45
#define RM1     r27
 
46
#define RM2     r28
 
47
#define RM3     r29
 
48
#define RM4     RA0
 
49
#define RM5     RA1
 
50
#define RM6     RA2
 
51
 
 
52
#define RY0     r30
 
53
#define RY1     r31
 
54
#define RY2     r15
 
55
 
 
56
#define RQ0     r16
 
57
#define RQ1     r17
 
58
#define RQ2     r18
 
59
#define RQ3     r19
 
60
#define RQ4     r8
 
61
#define RQ5     r9
 
62
 
 
63
#define RD0     r20
 
64
#define RD1     r21
 
65
#define RD2     r10
 
66
#define RD3     r11
 
67
#define RD4     r12
 
68
#define RD5     r13
 
69
#define RD6     r14
 
70
 
 
71
#define REM     RD0
 
72
 
 
73
FUNCTION cbrt
 
74
 
 
75
/* Division by 3.
 
76
   Input:
 
77
        rA3     - arg
 
78
   Output:
 
79
        rA3     - quotient
 
80
        REM     - remainder
 
81
        RY0     - zero (was counter)
 
82
   Scratch:
 
83
        r0
 
84
 */
 
85
#if  defined(__AVR_ENHANCED__) && __AVR_ENHANCED__
 
86
.Ldiv3: mov     REM, rA3        ; save
 
87
        ldi     RY0, 85
 
88
        inc     rA3
 
89
        mul     rA3, RY0
 
90
        mov     rA3, r1         ; quotient (((rA3 + 1) * 85) / 256)
 
91
        ldi     RY0, 3
 
92
        mul     RY0, rA3        ; r1 := 0, as the result is less than 256
 
93
        sub     REM, r0         ; remainder
 
94
        clr     RY0             ; API
 
95
        ret
 
96
#else
 
97
.Ldiv3: sub     REM, REM        ; clear remainder and carry
 
98
        ldi     RY0, 8          ; loop counter
 
99
        rol     rA3
 
100
1:      rol     REM
 
101
        cpi     REM, 3
 
102
        brlo    2f
 
103
        subi    REM, 3
 
104
2:      rol     rA3
 
105
        dec     RY0
 
106
        brne    1b
 
107
        com     rA3             ; because C flag was complemented in loop
 
108
        ret
 
109
#endif
 
110
 
 
111
0:      rjmp    _U(__fp_mpack)
 
112
 
 
113
ENTRY cbrt
 
114
  ; split and check arg.
 
115
        rcall   _U(__fp_splitA)
 
116
        brcs    0b              ; !isfinite(A)
 
117
        tst     rA3
 
118
        breq    0b              ; return 0 with original sign
 
119
 
 
120
  ; save registers
 
121
        .irp    .L_reg, r29,r28,r17,r16,r15,r14,r13,r12,r11,r10,r9,r8
 
122
        push    \.L_reg
 
123
        .endr
 
124
 
 
125
/* Calculate exponent.
 
126
 */
 
127
        subi    rA3, 127        ; bias
 
128
        brsh    5f
 
129
  ; exponent was < 0
 
130
        neg     rA3
 
131
  ; normalize, if A is subnormal
 
132
        tst     rA2
 
133
        brmi    2f
 
134
1:      inc     rA3     ; increment absolute value of negative exponent
 
135
        lsl     rA0
 
136
        rol     rA1
 
137
        rol     rA2
 
138
        brpl    1b
 
139
  ; division
 
140
2:      rcall   .Ldiv3
 
141
  ; reverse remainder
 
142
        dec     REM
 
143
        brmi    4f              ; remainder was 0
 
144
        brne    3f              ; REM: 2 --> 1
 
145
        subi    REM, -2         ; REM: 1 --> 2
 
146
3:      inc     rA3             ; correct quotient
 
147
  ; restore sign of exponent
 
148
4:      neg     rA3
 
149
        rjmp    6f
 
150
  ; exponent was >= 0
 
151
5:      rcall   .Ldiv3
 
152
  ; save result exponent
 
153
6:      subi    rA3, lo8(-127)
 
154
        push    rA3
 
155
 
 
156
  ; clear
 
157
        clr     RY1             ; RY0 == 0 after .Ldiv3 function
 
158
        clr     RY2
 
159
        X_movw  RQ0, RY0
 
160
        X_movw  RQ2, RY0
 
161
        X_movw  RQ4, RY0
 
162
        X_movw  RM0, RY0
 
163
        X_movw  RM2, RY0
 
164
 
 
165
  ; shift mantissa by 1..3 positions
 
166
7:      lsl     RA0
 
167
        rol     RA1
 
168
        rol     RA2
 
169
        rol     RM0
 
170
        dec     REM
 
171
        brpl    7b
 
172
 
 
173
/* --------------------------------------------------------------------
 
174
   Register usage:
 
175
        RCNT
 
176
        RA0..RA2
 
177
        RM0..RM2
 
178
        RY0
 
179
        RQ0..RQ1
 
180
        RD0..RD2
 
181
   Free registers for temporary values:
 
182
        RD4..RD6
 
183
 */
 
184
        ldi     RCNT, 8
 
185
.Loop1:
 
186
  ; RQ <<= 2
 
187
        lsl     RQ0
 
188
        rol     RQ1
 
189
        lsl     RQ0
 
190
        rol     RQ1
 
191
  ; RY <<= 1
 
192
        lsl     RY0
 
193
  ; RD = RY + RQ
 
194
        X_movw  RD0, RQ0
 
195
        clr     RD2
 
196
        add     RD0, RY0
 
197
        adc     RD1, r1
 
198
        adc     RD2, r1
 
199
  ; save RD
 
200
        X_movw  RD4, RD0
 
201
        mov     RD6, RD2
 
202
  ; RD <<= 1
 
203
        lsl     RD0
 
204
        rol     RD1
 
205
        rol     RD2
 
206
  ; RD += RY + RQ
 
207
        add     RD0, RD4
 
208
        adc     RD1, RD5
 
209
        adc     RD2, RD6
 
210
  ; RD |= 1
 
211
        ori     RD0, 1
 
212
  ; RM -= RD
 
213
        sub     RM0, RD0
 
214
        sbc     RM1, RD1
 
215
        sbc     RM2, RD2
 
216
        brsh    11f
 
217
  ; restore RM
 
218
        add     RM0, RD0
 
219
        adc     RM1, RD1
 
220
        adc     RM2, RD2
 
221
        rjmp    12f
 
222
  ; RQ += RY << 1
 
223
11:     X_movw  RD0, RY0
 
224
        lsl     RD0
 
225
        rol     RD1
 
226
        add     RQ0, RD0
 
227
        adc     RQ1, RD1
 
228
  ; RQ |= 1
 
229
        ori     RQ0, 1
 
230
  ; RY |= 1
 
231
        ori     RY0, 1
 
232
  ; RM = (RM << 3) <-- (RA << 3)
 
233
12:     ldi     RD0, 3
 
234
13:     lsl     RA0
 
235
        rol     RA1
 
236
        rol     RA2
 
237
        rol     RM0
 
238
        rol     RM1
 
239
        rol     RM2
 
240
        dec     RD0
 
241
        brne    13b
 
242
  ; ... while (--RCNT)
 
243
        dec     RCNT
 
244
        brne    .Loop1
 
245
 
 
246
/* --------------------------------------------------------------------
 
247
 */
 
248
        ldi     RCNT, 16
 
249
.Loop2:
 
250
  ; RQ <<= 2
 
251
20:     lsl     RQ0
 
252
        rol     RQ1
 
253
        rol     RQ2
 
254
        rol     RQ3
 
255
        rol     RQ4
 
256
        rol     RQ5
 
257
        com     r1
 
258
        brne    20b
 
259
  ; RY <<= 1
 
260
        lsl     RY0
 
261
        rol     RY1
 
262
        rol     RY2
 
263
  ; RD = 0
 
264
        clr     r0
 
265
        X_movw  RD0, r0
 
266
        X_movw  RD2, r0
 
267
        X_movw  RD4, r0
 
268
        clr     RD6
 
269
  ; RD += RQ
 
270
21:     add     RD0, RQ0
 
271
        adc     RD1, RQ1
 
272
        adc     RD2, RQ2
 
273
        adc     RD3, RQ3
 
274
        adc     RD4, RQ4
 
275
        adc     RD5, RQ5
 
276
        adc     RD6, r1
 
277
  ; RD += RY
 
278
        add     RD0, RY0
 
279
        adc     RD1, RY1
 
280
        adc     RD2, RY2
 
281
        adc     RD3, r1
 
282
        adc     RD4, r1
 
283
        adc     RD5, r1
 
284
        adc     RD6, r1
 
285
  ;
 
286
        com     r0
 
287
        breq    22f
 
288
  ; RD <<= 1
 
289
        lsl     RD0
 
290
        rol     RD1
 
291
        rol     RD2
 
292
        rol     RD3
 
293
        rol     RD4
 
294
        rol     RD5
 
295
        rol     RD6
 
296
        rjmp    21b
 
297
  ; RM -= RD
 
298
22:     sub     RM0, RD0
 
299
        sbc     RM1, RD1
 
300
        sbc     RM2, RD2
 
301
        sbc     RM3, RD3
 
302
        sbc     RM4, RD4
 
303
        sbc     RM5, RD5
 
304
        sbc     RM6, RD6
 
305
        brsh    23f
 
306
  ; restore RM
 
307
        add     RM0, RD0
 
308
        adc     RM1, RD1
 
309
        adc     RM2, RD2
 
310
        adc     RM3, RD3
 
311
        adc     RM4, RD4
 
312
        adc     RM5, RD5
 
313
        adc     RM6, RD6
 
314
        rjmp    24f
 
315
 
 
316
  ; RQ += 2*RY
 
317
23:     add     RQ0, RY0
 
318
        adc     RQ1, RY1
 
319
        adc     RQ2, RY2
 
320
        adc     RQ3, r1
 
321
        adc     RQ4, r1
 
322
        adc     RQ5, r1
 
323
        com     r0
 
324
        brne    23b
 
325
  ; RQ |= 1
 
326
        ori     RQ0, 1
 
327
  ; RY |= 1
 
328
        ori     RY0, 1
 
329
  ; RM <<= 3
 
330
24:     ldi     RD0, 3
 
331
25:     lsl     RM0
 
332
        rol     RM1
 
333
        rol     RM2
 
334
        rol     RM3
 
335
        rol     RM4
 
336
        rol     RM5
 
337
        rol     RM6
 
338
        dec     RD0
 
339
        brne    25b
 
340
        
 
341
        dec     RCNT
 
342
        breq    26f
 
343
        rjmp    .Loop2
 
344
 
 
345
  ; make result
 
346
26:     X_movw  rA0, RY0
 
347
        mov     rA2, RY2
 
348
        pop     rA3
 
349
        lsl     rA2
 
350
        lsr     rA3
 
351
        ror     rA2
 
352
        bld     rA3, 7                  ; sign
 
353
 
 
354
  ; restore registers and return
 
355
        .irp    .L_reg, r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r28,r29
 
356
        pop     \.L_reg
 
357
        .endr
 
358
        ret
 
359
 
 
360
ENDFUNC