~ubuntu-branches/ubuntu/gutsy/avr-libc/gutsy

« back to all changes in this revision

Viewing changes to libm/fplib/mulsf3x.S

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2006-11-15 21:12:47 UTC
  • mfrom: (3.1.2 feisty)
  • Revision ID: james.westby@ubuntu.com-20061115211247-b7qhgnb6o49v5zsg
Tags: 1:1.4.5-2
* Convertion to debheler fixed (closes: #398220)
* Reference to /usr/share/common-licenses in copyright file

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
   POSSIBILITY OF SUCH DAMAGE. 
33
33
*/
34
34
 
 
35
/* $Id: mulsf3x.S,v 1.7 2005/11/15 21:18:48 aesok Exp $ */
 
36
 
35
37
/*
36
38
    mulsf3x.S is part of     FPlib V 0.3.0       ported to avr-as
37
39
    for details see readme.fplib
46
48
 * RX  rA3 : rA2:rA1:rA0:rAE
47
49
 */
48
50
 
49
 
#if !defined(DOXYGEN)
 
51
#if !defined(__DOXYGEN__)
50
52
 
51
53
#include "gasava.inc"
 
54
#include "macros.inc"
52
55
#include "fplib.inc"
53
56
 
54
57
          TEXT_SEG(fplib, __mulsf3x)
56
59
 
57
60
GLOBAL(__mulsf3x)
58
61
    TST     rA3
59
 
    BREQ    ___mulsf3x_ZERO
60
 
 ___mulsf3_10:
 
62
    BREQ    2f
 
63
 
61
64
    TST     rB3
62
 
    BREQ    ___mulsf3x_ZERO
 
65
    BREQ    2f
63
66
 
64
 
 ___mulsf3x_00:
65
67
     SUBI    rA3,0x7F          ; exp(A) now signed char
66
68
     SUBI    rB3,0x7F          ; exp(B) now signed char
67
69
 
68
70
     ADD     rA3,rB3           ; add two signed registers
69
 
     BRVC    ___mulsf3x_20     ; no signed overflow
70
 
     BRMI    ___mulsf3x_INF    ; signed overflow : if now negative -> positive overflow
71
 
 ___mulsf3x_ZERO:
 
71
     BRVC    1f                ; no signed overflow
 
72
     BRMI    100f              ; signed overflow : if now negative -> positive overflow
 
73
2:
72
74
     RJMP    _U(__fp_zerox)
73
75
 
74
 
 ___mulsf3x_20:
 
76
1:
75
77
     SUBI    rA3,0x81          ; = ADI,0x7F
76
78
     CPI     rA3,0xFF
77
 
     BREQ    ___mulsf3x_ZERO   ; no (unsigned overflow) -> signed underflow
 
79
     BREQ    2b                ; no (unsigned overflow) -> signed underflow
 
80
 
 
81
#ifdef __AVR_ENHANCED__
 
82
 
 
83
        ; this section of code is used by processors which have MUL instruction
 
84
 
 
85
    ; now multiply mantissa A[rA2:rA1:rA0] * B[rB2:rB1:rB0]
 
86
    ; result : [rr5:rr4:rr3:rr2:rr1:rr0]
 
87
    
 
88
    ; definitions used by calculation
 
89
    #define rr2 rAE
 
90
    #define rr3 rTI1
 
91
    #define rr4 rBE
 
92
    #define rr5 rB3
 
93
    #define rmh r1      ; the multiply result high register
 
94
    #define rml r0      ; the multiply result low register
 
95
    
 
96
    MUL     rA0, rB0    ; 0+0 = 0,1
 
97
    MOV     rr4, rmh    ; rr1 == rr4
 
98
    PUSH    rml         ; rr0 finished
 
99
    
 
100
    CLR     rr2
 
101
    MUL     rA0, rB1    ; 0+1 = 1,2
 
102
    ADD     rr4, rml
 
103
    ADC     rr2, rmh
 
104
    CLR     rr3
 
105
    MUL     rA1, rB0    ; 1+0 = 1,2,3
 
106
    ADD     rr4, rml
 
107
    ADC     rr2, rmh
 
108
    ADC     rr3, rr3
 
109
    PUSH    rr4         ; rr1 finished
 
110
    
 
111
    CLR     rr4
 
112
    MUL     rA0, rB2    ; 0+2 = 2,3
 
113
    ADD     rr2, rml
 
114
    ADC     rr3, rmh
 
115
    MUL     rA1, rB1    ; 1+1 = 2,3,4
 
116
    ADD     rr2, rml
 
117
    ADC     rr3, rmh
 
118
    ADC     rr4, rr4
 
119
    CLR     rA0
 
120
    MUL     rA2, rB0    ; 2+0 = 2,3,4
 
121
    ADD     rr2, rml
 
122
    ADC     rr3, rmh
 
123
    ADC     rr4, rA0
 
124
    
 
125
    CLR     rr5
 
126
    MUL     rA1, rB2    ; 1+2 = 3,4,5
 
127
    ADD     rr3, rml
 
128
    ADC     rr4, rmh
 
129
    ADC     rr5, rr5
 
130
    MUL     rA2, rB1    ; 2+1 = 3,4,5
 
131
    ADD     rr3, rml
 
132
    ADC     rr4, rmh
 
133
    ADC     rr5, rA0
 
134
    
 
135
    MUL     rA2, rB2    ; 2+2 = 4,5
 
136
    ADD     rr4, rml
 
137
    ADC     rr5, rmh   
 
138
 
 
139
    ; converting result to original format
 
140
    MOV     rA2, rr5
 
141
    MOV     rA1, rr4
 
142
    MOV     rA0, rr3
 
143
    ; rr2 is the right one, no need to move
 
144
 
 
145
    #undef rr5
 
146
    #undef rr4
 
147
    #undef rr3
 
148
    ; definitions used by result
 
149
    #define rr5 rA2
 
150
    #define rr4 rA1
 
151
    #define rr3 rA0
 
152
   // #define rr2 rAE
 
153
    #define rr1 rT1c
 
154
    #define rr0 rT0
 
155
    #define rb5 rTI1
 
156
    #define rb4 rBE
 
157
    #define rb3 rB3
 
158
 
 
159
    ; take out the lowest bytes from stack
 
160
    POP     rr1
 
161
    POP     rr0
 
162
; +++ 44 instructions +++
 
163
 
 
164
#else // __AVR_ENHANCED__
 
165
 
 
166
        ; this section of code is used by processors which have not MUL instruction
78
167
 
79
168
    ; now multiply mantissa A[rA2:rA1:rA0] * B[rb5:rb4:rb3:rB2:rB1:rB0]
80
169
    ; result : [rr5:rr4:rr3:rr2:rr1:rr0]
97
186
    CLR     rb3
98
187
 
99
188
    LDI     loop,8           ; loop counter
100
 
 ___mulsf3x_100:
 
189
1:
101
190
    LSR     rb4
102
 
    BRCC    ___mulsf3x_101
 
191
    BRCC    2f
103
192
    ADD     rr0,rB0
104
193
    adc     rr1,rB1
105
194
    adc     rr2,rB2
106
195
    adc     rr3,rb3
107
 
 ___mulsf3x_101:
 
196
2:
108
197
    ADD     rB0,rB0
109
198
    adc     rB1,rB1
110
199
    adc     rB2,rB2
111
200
    adc     rb3,rb3
112
201
    DEC     loop
113
 
    BRNE    ___mulsf3x_100    ;
 
202
    BRNE    1b
114
203
    LDI     loop,8           ; loop counter
115
204
 
116
205
    MOV     rb5,rA1          ; rb5 not yet needed
117
206
    CLR     rr4              ; rb4 is allready clear
118
207
    LDI     loop,8           ; loop counter
119
 
 ___mulsf3x_200:
 
208
1:
120
209
    LSR     rb5
121
 
    BRCC    ___mulsf3x_201
 
210
    BRCC    2f
122
211
    ADD     rr1,rB1
123
212
    adc     rr2,rB2
124
213
    adc     rr3,rb3
125
214
    adc     rr4,rb4
126
 
 ___mulsf3x_201:
 
215
2:
127
216
    ADD     rB1,rB1
128
217
    adc     rB2,rB2
129
218
    adc     rb3,rb3
130
219
    adc     rb4,rb4
131
220
    DEC     loop
132
 
    BRNE    ___mulsf3x_200    ;
 
221
    BRNE    1b
133
222
 
134
223
    MOV     loop,rA2          ; loop no longer needed, check
135
224
    CLR     rr5               ; rb5 is allready clear
136
 
 ___mulsf3x_300:
 
225
1:
137
226
    LSR     loop
138
 
    BRCC    ___mulsf3x_301
 
227
    BRCC    2f
139
228
    ADD     rr2,rB2
140
229
    adc     rr3,rb3
141
230
    adc     rr4,rb4
142
231
    adc     rr5,rb5
143
 
 ___mulsf3x_301:
 
232
2:
144
233
    ADD     rB2,rB2
145
234
    adc     rb3,rb3
146
235
    adc     rb4,rb4
147
236
    adc     rb5,rb5
148
237
    TST     loop
149
 
    BRNE    ___mulsf3x_300    ;
 
238
    BRNE    1b
 
239
; +++ 49 instructions +++
 
240
 
 
241
#endif // __AVR_ENHANCED__
 
242
 
150
243
 
151
244
    ; multiplication done : result in rr5:rr4:rr3:rr2:rr1:rr0
152
245
    ;                              =  rA2:rA1:rA0:rAE:rr1:rr0
153
 
 ___mulsf3x_400: ;  normalize  1.0 * 1.0      = 1.0
154
 
               ;                          0x800000 * 0x800000 = 0x40 00 00 00 00 00
155
 
               ;                          1.999999 * 1.999999 = 3.99999 ~ 4.0
156
 
               ;                          0xFFFFFF * 0xFFFFFF = 0xFF FF FE 00 00 01
 
246
    ;  normalize  1.0 * 1.0      = 1.0
 
247
    ;                          0x800000 * 0x800000 = 0x40 00 00 00 00 00
 
248
    ;                          1.999999 * 1.999999 = 3.99999 ~ 4.0
 
249
    ;                          0xFFFFFF * 0xFFFFFF = 0xFF FF FE 00 00 01
157
250
 
158
251
    TST     rA2
159
 
    BRPL    ___mulsf3x_405    ; if MSB erg is clr
 
252
    BRPL    1f                ; if MSB erg is clr
160
253
    INC     rA3               ;
161
 
    BRNE    ___mulsf3x_420
162
 
 ___mulsf3x_INF:
 
254
    BRNE    2f
 
255
100:
163
256
    RJMP    _U(__fp_nanx)     ; returns to ___mulsf3 or a high level function : rT1c ok
164
 
 ___mulsf3x_405:
 
257
1:
165
258
    ADD     rr0,rr0
166
259
    adc     rr1,rr1
167
260
    adc     rAE,rAE
169
262
    adc     rA1,rA1
170
263
    adc     rA2,rA2
171
264
 
172
 
 ___mulsf3x_420:
 
265
2:
173
266
    OR    rr0,rr1             ; rr0 = rT0 which holds the mantissae extension beyond rAE
174
267
    RET
175
268
 
176
269
          ENDFUNC
177
270
 
178
 
#endif /* not DOXYGEN */
 
271
#endif /* not __DOXYGEN__ */