65
67
SUBI rA3,0x7F ; exp(A) now signed char
66
68
SUBI rB3,0x7F ; exp(B) now signed char
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
BRVC 1f ; no signed overflow
72
BRMI 100f ; signed overflow : if now negative -> positive overflow
72
74
RJMP _U(__fp_zerox)
75
77
SUBI rA3,0x81 ; = ADI,0x7F
77
BREQ ___mulsf3x_ZERO ; no (unsigned overflow) -> signed underflow
79
BREQ 2b ; no (unsigned overflow) -> signed underflow
81
#ifdef __AVR_ENHANCED__
83
; this section of code is used by processors which have MUL instruction
85
; now multiply mantissa A[rA2:rA1:rA0] * B[rB2:rB1:rB0]
86
; result : [rr5:rr4:rr3:rr2:rr1:rr0]
88
; definitions used by calculation
93
#define rmh r1 ; the multiply result high register
94
#define rml r0 ; the multiply result low register
96
MUL rA0, rB0 ; 0+0 = 0,1
97
MOV rr4, rmh ; rr1 == rr4
98
PUSH rml ; rr0 finished
101
MUL rA0, rB1 ; 0+1 = 1,2
105
MUL rA1, rB0 ; 1+0 = 1,2,3
109
PUSH rr4 ; rr1 finished
112
MUL rA0, rB2 ; 0+2 = 2,3
115
MUL rA1, rB1 ; 1+1 = 2,3,4
120
MUL rA2, rB0 ; 2+0 = 2,3,4
126
MUL rA1, rB2 ; 1+2 = 3,4,5
130
MUL rA2, rB1 ; 2+1 = 3,4,5
135
MUL rA2, rB2 ; 2+2 = 4,5
139
; converting result to original format
143
; rr2 is the right one, no need to move
148
; definitions used by result
159
; take out the lowest bytes from stack
162
; +++ 44 instructions +++
164
#else // __AVR_ENHANCED__
166
; this section of code is used by processors which have not MUL instruction
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]
99
188
LDI loop,8 ; loop counter
113
BRNE ___mulsf3x_100 ;
114
203
LDI loop,8 ; loop counter
116
205
MOV rb5,rA1 ; rb5 not yet needed
117
206
CLR rr4 ; rb4 is allready clear
118
207
LDI loop,8 ; loop counter
132
BRNE ___mulsf3x_200 ;
134
223
MOV loop,rA2 ; loop no longer needed, check
135
224
CLR rr5 ; rb5 is allready clear
149
BRNE ___mulsf3x_300 ;
239
; +++ 49 instructions +++
241
#endif // __AVR_ENHANCED__
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
159
BRPL ___mulsf3x_405 ; if MSB erg is clr
252
BRPL 1f ; if MSB erg is clr
163
256
RJMP _U(__fp_nanx) ; returns to ___mulsf3 or a high level function : rT1c ok