«« ( Date ) »» // «« ( Thread ) »» // csidc - 2004

Deljenje

by Stojlljkovic Predrag
subota, 03. april 2004 - 04:07.

Napravio sam funkciju za deljenje float brojeva, zapisanih u sledecem obliku:
gornjih 16 bita predstavljaju eksponent E(signed integer). Donjih 16 bita predstavljaju apsolutnu vrednost mantise M (nizih 15 bita) i znak S (MSB tj. bit 15). Najvisi bit mantise je gotovo uvek jednak jedinici (bit 14) osim kada je u pitanju zapis broja 0 kada je mantisa jednaka 0. Broj se izracunava kao (-1)^S * 0.M * 2^E. Algoritam koji sam ja napravio za deljenje ovakva dva broja se izvsava u oko 5 ciklusa i glasi:


divf .macro deljenik, delilac, kolicnik
st deljenik+1, ar1
st delilac+1, ar2
st kolicnik, ar3
ldu *ar2,b ;ucitavanje delioca u akumulator
and #0x7fff, b ;deliocu se brise bit znaka i ta vrednost
stl b, *ar3+ ;smesta u prvu rec kolicnika
ldu *ar2-, b ;racunamo znak kolicnika
xor *ar1, b
and #0x8000, b ;ovde se u b nalazi znak na bitu 15
stl b, *ar3- ;pamcenje znaka u drugu rec kolicnika
ldu *ar1-, a ;unos apsolutne vrednosti mantise
and #0x7fff, a ;deljenika u akumulator
sftl a, 15 ;deljenik se shiftuje za 15
rpt #13 ;celobrojno deljnenje mantisa
subc *ar3, a
subc *ar3+, a ;u akumulatoru je u donjih 15 bita kolicnik
and #0x7fff,a ;upisivanje 0 u ostale bitove akumulatora
sftl a,1
sftl a,15 ;ovo je zbog toga da mantisa ima 1 na
sftc a ;mestu najviseg bita
bcd divl1, NTC ;skok ako je bilo pomeranja
ld *ar1, b ;eksponent se racuna u b
sub *ar2, b ;oduzimanjem eksponenata,
add #1, b ;jedinice ako je bilo pomeranja
divl1:
sftl a, -16 ;pomeranje rezultata u donju rec akumulatora
or *ar3, a ;dodavanje znaka uz mantisu
stl a, *ar3- ;upis mantise u kolicnik
stl b, *ar3 ;upis eksponenata u kolicnik
.endm

Grujo, ako imas malo vremena, molio bih te da istestiras algoritam (ja jesam i nisam nasao greske, osim sto se podrazumeva da se ne vrsi deljenje nulom, koje necemo imati u nasem slucaju), i da vidis da li moze jos da se optimizuje (ovo je gotovo najbolje sto sam ja uspeo, eventualno bi moglo da se ustedi 1 ili 2 ciklusa tako sto se broj #0x7fff smesti u memoriju, pa se vrsi AND sa memorijom, ali je to mala usteda vremena)