56
56
; normalize, if A is subnormal
58
58
rcall _U(__fp_norm2)
59
; calculate result exponent
62
; expand A mantissa to rAE.rA2.rA1.rA0
64
brcc 1f ; after 'ror rA3'
78
; save temporary regs.
82
/* arg's mantissa: rAE.rA2.rA1.rA0
84
moving bit: mvb2.mvb1.mvb0
85
remain value: rem3.rem2.rem1.rem0 */
138
cpc rem3, rAE ; C is set if rem < A
142
; pop temporary regs.
145
; merge result and return
64
clr msk0 ; msk1=R1 already 0
65
ldi msk2, 0x60 ; Initial rotation mask =
66
; 01100000.00000000.00000000
68
X_movw rB0, msk0 ; Initial developing root =
69
; 10100000.00000000.00000000
71
/* TODO: Now the Avr-libs does not have an infrastructure to build and
72
*test automaticaly* with both OPTIMIZE_SPEED definitions. So the
73
one variant is enabled today only.
75
#if 1 /* defined(OPTIMIZE_SPEED) && OPTIMIZE_SPEED */
77
;** Optimized for speed (9 code words larger than size optimized,
78
; 67 less cycles in average)
82
ror rA3 ; Divide exponent by 2, C==>exponent was odd
83
brcc 1f ; Jump for even exponent in argument
84
subi rA2, lo8(-0x40) ; Initial remainder for odd exponent.
86
; Loop for upper 23 bits
89
rol rA2 ; Shift left remainder argument
90
brcs 2f ; C --> Bit is always 1 (rA * 2 gave C)
93
cpc rB2, rA2 ; Does test value fit?
94
brcc 3f ; NC --> nope, bit is 0
97
sbc rA2, rB2 ; Prepare remainder argument for next bits
100
or rB2, msk2 ; Set developing bit to 1
103
ror msk0 ; Shift right mask, C --> end loop
106
eor rB2, msk2 ; Shift right test bit in developing root
107
brcc .Loop ; Develop 23 bits of the sqrt
109
; Loop for bit 0 and rounding
112
rol rA2 ; Shift left remainder argument
113
brcs 4f ; C--> Last bits always 1
116
cpc rB2, rA2 ; Test for last bit 1
117
brcc 5f ; Nope, stays the same
118
4: sbc rA0, rB0 ; MUST BE SBC !!
120
sbc rA2, rB2 ; Prepare remainder argument for next bit
123
adc rB2, msk1 ; Add 1 to result
124
5: com msk2 ; ZF if second time
125
brne .Loop1 ; 1 for last bit, 1 for rounding
127
#else /* vs. to OPTIMIZE_SPEED */
128
;** Optimized for size (9 code words smaller than speed optimized,
129
; 67 more cycles in average)
133
clr tv ; Test value for end of loop
134
subi rA2, 0x40 ; Initial remainder for odd exponent
136
ror rA3 ; Divide exponent by 2, C==>exponent was odd
137
brcs 3f ; Jump for odd exponent in argument
138
subi rA2, 0x40 ; Initial remainder for even exponent, C=0
140
; Loop for all 24 bits
141
.Loop: brcc 2f ; NC --> nope, bit is 0
142
cp msk2, tv ; Only needed to get the proper rounding
146
sbc rA2, rB2 ; Prepare remainder argument for next bits
149
or rB2, msk2 ; Set developing bit to 1
152
ror msk0 ; Shift right mask, C --> end loop
153
rol tv ; Bit 1 set if end of loop
156
eor rB2, msk2 ; Shift right test bit in developing root
159
rol rA2 ; Shift left remainder argument (C used
172
adc rB2, msk1 ; Rounded mantissa ready (msk1=0)
174
#endif /* !OPTIMIZE_SPEED */
148
subi rA3, lo8(-127) ; exponent bias
177
mov rA2, rB2 ; Copy to rA
179
subi rA3, lo8(-127) ; exponent bias