| 32 |
POSSIBILITY OF SUCH DAMAGE. |
POSSIBILITY OF SUCH DAMAGE. |
| 33 |
*/ |
*/ |
| 34 |
|
|
| 35 |
|
/* $Id$ */ |
| 36 |
|
|
| 37 |
/* |
/* |
| 38 |
mulsf3x.S is part of FPlib V 0.3.0 ported to avr-as |
mulsf3x.S is part of FPlib V 0.3.0 ported to avr-as |
| 39 |
for details see readme.fplib |
for details see readme.fplib |
| 59 |
|
|
| 60 |
GLOBAL(__mulsf3x) |
GLOBAL(__mulsf3x) |
| 61 |
TST rA3 |
TST rA3 |
| 62 |
BREQ ___mulsf3x_ZERO |
BREQ 2f |
| 63 |
___mulsf3_10: |
|
| 64 |
TST rB3 |
TST rB3 |
| 65 |
BREQ ___mulsf3x_ZERO |
BREQ 2f |
| 66 |
|
|
|
___mulsf3x_00: |
|
| 67 |
SUBI rA3,0x7F ; exp(A) now signed char |
SUBI rA3,0x7F ; exp(A) now signed char |
| 68 |
SUBI rB3,0x7F ; exp(B) now signed char |
SUBI rB3,0x7F ; exp(B) now signed char |
| 69 |
|
|
| 70 |
ADD rA3,rB3 ; add two signed registers |
ADD rA3,rB3 ; add two signed registers |
| 71 |
BRVC ___mulsf3x_20 ; no signed overflow |
BRVC 1f ; no signed overflow |
| 72 |
BRMI ___mulsf3x_INF ; signed overflow : if now negative -> positive overflow |
BRMI 100f ; signed overflow : if now negative -> positive overflow |
| 73 |
___mulsf3x_ZERO: |
2: |
| 74 |
RJMP _U(__fp_zerox) |
RJMP _U(__fp_zerox) |
| 75 |
|
|
| 76 |
___mulsf3x_20: |
1: |
| 77 |
SUBI rA3,0x81 ; = ADI,0x7F |
SUBI rA3,0x81 ; = ADI,0x7F |
| 78 |
CPI rA3,0xFF |
CPI rA3,0xFF |
| 79 |
BREQ ___mulsf3x_ZERO ; no (unsigned overflow) -> signed underflow |
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 |
| 167 |
|
|
| 168 |
; now multiply mantissa A[rA2:rA1:rA0] * B[rb5:rb4:rb3:rB2:rB1:rB0] |
; now multiply mantissa A[rA2:rA1:rA0] * B[rb5:rb4:rb3:rB2:rB1:rB0] |
| 169 |
; result : [rr5:rr4:rr3:rr2:rr1:rr0] |
; result : [rr5:rr4:rr3:rr2:rr1:rr0] |
| 186 |
CLR rb3 |
CLR rb3 |
| 187 |
|
|
| 188 |
LDI loop,8 ; loop counter |
LDI loop,8 ; loop counter |
| 189 |
___mulsf3x_100: |
1: |
| 190 |
LSR rb4 |
LSR rb4 |
| 191 |
BRCC ___mulsf3x_101 |
BRCC 2f |
| 192 |
ADD rr0,rB0 |
ADD rr0,rB0 |
| 193 |
adc rr1,rB1 |
adc rr1,rB1 |
| 194 |
adc rr2,rB2 |
adc rr2,rB2 |
| 195 |
adc rr3,rb3 |
adc rr3,rb3 |
| 196 |
___mulsf3x_101: |
2: |
| 197 |
ADD rB0,rB0 |
ADD rB0,rB0 |
| 198 |
adc rB1,rB1 |
adc rB1,rB1 |
| 199 |
adc rB2,rB2 |
adc rB2,rB2 |
| 200 |
adc rb3,rb3 |
adc rb3,rb3 |
| 201 |
DEC loop |
DEC loop |
| 202 |
BRNE ___mulsf3x_100 ; |
BRNE 1b |
| 203 |
LDI loop,8 ; loop counter |
LDI loop,8 ; loop counter |
| 204 |
|
|
| 205 |
MOV rb5,rA1 ; rb5 not yet needed |
MOV rb5,rA1 ; rb5 not yet needed |
| 206 |
CLR rr4 ; rb4 is allready clear |
CLR rr4 ; rb4 is allready clear |
| 207 |
LDI loop,8 ; loop counter |
LDI loop,8 ; loop counter |
| 208 |
___mulsf3x_200: |
1: |
| 209 |
LSR rb5 |
LSR rb5 |
| 210 |
BRCC ___mulsf3x_201 |
BRCC 2f |
| 211 |
ADD rr1,rB1 |
ADD rr1,rB1 |
| 212 |
adc rr2,rB2 |
adc rr2,rB2 |
| 213 |
adc rr3,rb3 |
adc rr3,rb3 |
| 214 |
adc rr4,rb4 |
adc rr4,rb4 |
| 215 |
___mulsf3x_201: |
2: |
| 216 |
ADD rB1,rB1 |
ADD rB1,rB1 |
| 217 |
adc rB2,rB2 |
adc rB2,rB2 |
| 218 |
adc rb3,rb3 |
adc rb3,rb3 |
| 219 |
adc rb4,rb4 |
adc rb4,rb4 |
| 220 |
DEC loop |
DEC loop |
| 221 |
BRNE ___mulsf3x_200 ; |
BRNE 1b |
| 222 |
|
|
| 223 |
MOV loop,rA2 ; loop no longer needed, check |
MOV loop,rA2 ; loop no longer needed, check |
| 224 |
CLR rr5 ; rb5 is allready clear |
CLR rr5 ; rb5 is allready clear |
| 225 |
___mulsf3x_300: |
1: |
| 226 |
LSR loop |
LSR loop |
| 227 |
BRCC ___mulsf3x_301 |
BRCC 2f |
| 228 |
ADD rr2,rB2 |
ADD rr2,rB2 |
| 229 |
adc rr3,rb3 |
adc rr3,rb3 |
| 230 |
adc rr4,rb4 |
adc rr4,rb4 |
| 231 |
adc rr5,rb5 |
adc rr5,rb5 |
| 232 |
___mulsf3x_301: |
2: |
| 233 |
ADD rB2,rB2 |
ADD rB2,rB2 |
| 234 |
adc rb3,rb3 |
adc rb3,rb3 |
| 235 |
adc rb4,rb4 |
adc rb4,rb4 |
| 236 |
adc rb5,rb5 |
adc rb5,rb5 |
| 237 |
TST loop |
TST loop |
| 238 |
BRNE ___mulsf3x_300 ; |
BRNE 1b |
| 239 |
|
; +++ 49 instructions +++ |
| 240 |
|
|
| 241 |
|
#endif // __AVR_ENHANCED__ |
| 242 |
|
|
| 243 |
|
|
| 244 |
; multiplication done : result in rr5:rr4:rr3:rr2:rr1:rr0 |
; multiplication done : result in rr5:rr4:rr3:rr2:rr1:rr0 |
| 245 |
; = rA2:rA1:rA0:rAE:rr1:rr0 |
; = rA2:rA1:rA0:rAE:rr1:rr0 |
| 246 |
___mulsf3x_400: ; normalize 1.0 * 1.0 = 1.0 |
; normalize 1.0 * 1.0 = 1.0 |
| 247 |
; 0x800000 * 0x800000 = 0x40 00 00 00 00 00 |
; 0x800000 * 0x800000 = 0x40 00 00 00 00 00 |
| 248 |
; 1.999999 * 1.999999 = 3.99999 ~ 4.0 |
; 1.999999 * 1.999999 = 3.99999 ~ 4.0 |
| 249 |
; 0xFFFFFF * 0xFFFFFF = 0xFF FF FE 00 00 01 |
; 0xFFFFFF * 0xFFFFFF = 0xFF FF FE 00 00 01 |
| 250 |
|
|
| 251 |
TST rA2 |
TST rA2 |
| 252 |
BRPL ___mulsf3x_405 ; if MSB erg is clr |
BRPL 1f ; if MSB erg is clr |
| 253 |
INC rA3 ; |
INC rA3 ; |
| 254 |
BRNE ___mulsf3x_420 |
BRNE 2f |
| 255 |
___mulsf3x_INF: |
100: |
| 256 |
RJMP _U(__fp_nanx) ; returns to ___mulsf3 or a high level function : rT1c ok |
RJMP _U(__fp_nanx) ; returns to ___mulsf3 or a high level function : rT1c ok |
| 257 |
___mulsf3x_405: |
1: |
| 258 |
ADD rr0,rr0 |
ADD rr0,rr0 |
| 259 |
adc rr1,rr1 |
adc rr1,rr1 |
| 260 |
adc rAE,rAE |
adc rAE,rAE |
| 262 |
adc rA1,rA1 |
adc rA1,rA1 |
| 263 |
adc rA2,rA2 |
adc rA2,rA2 |
| 264 |
|
|
| 265 |
___mulsf3x_420: |
2: |
| 266 |
OR rr0,rr1 ; rr0 = rT0 which holds the mantissae extension beyond rAE |
OR rr0,rr1 ; rr0 = rT0 which holds the mantissae extension beyond rAE |
| 267 |
RET |
RET |
| 268 |
|
|