2005-04-16 15:20:36 -07:00
|
| round. s a 3 . 4 7 / 2 9 / 9 1
|
| handle r o u n d i n g a n d n o r m a l i z a t i o n t a s k s
|
|
|
| Copyright ( C ) M o t o r o l a , I n c . 1 9 9 0
| All R i g h t s R e s e r v e d
|
2006-02-11 17:55:48 -08:00
| For d e t a i l s o n t h e l i c e n s e f o r t h i s f i l e , p l e a s e s e e t h e
| file, R E A D M E , i n t h i s s a m e d i r e c t o r y .
2005-04-16 15:20:36 -07:00
| ROUND i d n t 2 ,1 | M o t o r o l a 0 4 0 F l o a t i n g P o i n t S o f t w a r e P a c k a g e
| section 8
# include " f p s p . h "
|
| round - - - r o u n d r e s u l t a c c o r d i n g t o p r e c i s i o n / m o d e
|
| a0 p o i n t s t o t h e i n p u t o p e r a n d i n t h e i n t e r n a l e x t e n d e d f o r m a t
| d1 ( h i g h w o r d ) c o n t a i n s r o u n d i n g p r e c i s i o n :
| ext = $ 0 0 0 0 x x x x
| sgl = $ 0 0 0 1 x x x x
| dbl = $ 0 0 0 2 x x x x
| d1 ( l o w w o r d ) c o n t a i n s r o u n d i n g m o d e :
| RN = $ x x x x00 0 0
| RZ = $ x x x x00 0 1
| RM = $ x x x x00 1 0
| RP = $ x x x x00 1 1
| d0 { 3 1 : 2 9 } c o n t a i n s t h e g ,r ,s b i t s ( e x t e n d e d )
|
| On r e t u r n t h e v a l u e p o i n t e d t o b y a0 i s c o r r e c t l y r o u n d e d ,
| a0 i s p r e s e r v e d a n d t h e g - r - s b i t s i n d0 a r e c l e a r e d .
| The r e s u l t i s n o t t y p e d - t h e t a g f i e l d i s i n v a l i d . T h e
| result i s s t i l l i n t h e i n t e r n a l e x t e n d e d f o r m a t .
|
| The I N E X b i t o f U S E R _ F P S R w i l l b e s e t i f t h e r o u n d e d r e s u l t w a s
| inexact ( i . e . i f a n y o f t h e g - r - s b i t s w e r e s e t ) .
|
.global round
round :
| If g =r =s =0 t h e n r e s u l t i s e x a c t a n d r o u n d i s d o n e , e l s e s e t
| the i n e x f l a g i n s t a t u s r e g a n d c o n t i n u e .
|
bsrs e x t _ g r s | t h i s s u b r o u t i n e l o o k s a t t h e
| : rounding p r e c i s i o n a n d s e t s
| ;the appropriate g-r-s bits.
tstl % d0 | i f g r s a r e z e r o , g o f o r c e
bne r n d _ c o n t | l o w e r b i t s t o z e r o f o r s i z e
swap % d1 | s e t u p d1 . w f o r r o u n d p r e c .
bra t r u n c a t e
rnd_cont :
|
| Use r o u n d i n g m o d e a s a n i n d e x i n t o a j u m p t a b l e f o r t h e s e m o d e s .
|
orl #i n x 2 a _ m a s k ,U S E R _ F P S R ( % a6 ) | s e t i n e x2 / a i n e x
lea m o d e _ t a b ,% a1
movel ( % a1 ,% d1 . w * 4 ) ,% a1
jmp ( % a1 )
|
| Jump t a b l e i n d e x e d b y r o u n d i n g m o d e i n d1 . w . A l l f o l l o w i n g a s s u m e s
| grs ! = 0 .
|
mode_tab :
.long rnd_near
.long rnd_zero
.long rnd_mnus
.long rnd_plus
|
| ROUND P L U S I N F I N I T Y
|
| If s i g n o f f p n u m b e r = 0 ( p o s i t i v e ) , t h e n a d d 1 t o l .
|
rnd_plus :
swap % d1 | s e t u p d1 f o r r o u n d p r e c .
tstb L O C A L _ S G N ( % a0 ) | c h e c k f o r s i g n
bmi t r u n c a t e | i f p o s i t i v e t h e n t r u n c a t e
movel #0xffffffff ,% d0 | f o r c e g ,r ,s t o b e a l l f ' s
lea a d d _ t o _ l ,% a1
movel ( % a1 ,% d1 . w * 4 ) ,% a1
jmp ( % a1 )
|
| ROUND M I N U S I N F I N I T Y
|
| If s i g n o f f p n u m b e r = 1 ( n e g a t i v e ) , t h e n a d d 1 t o l .
|
rnd_mnus :
swap % d1 | s e t u p d1 f o r r o u n d p r e c .
tstb L O C A L _ S G N ( % a0 ) | c h e c k f o r s i g n
bpl t r u n c a t e | i f n e g a t i v e t h e n t r u n c a t e
movel #0xffffffff ,% d0 | f o r c e g ,r ,s t o b e a l l f ' s
lea a d d _ t o _ l ,% a1
movel ( % a1 ,% d1 . w * 4 ) ,% a1
jmp ( % a1 )
|
| ROUND Z E R O
|
| Always t r u n c a t e .
rnd_zero :
swap % d1 | s e t u p d1 f o r r o u n d p r e c .
bra t r u n c a t e
|
|
| ROUND N E A R E S T
|
| If ( g =1 ) , t h e n a d d 1 t o l a n d i f ( r =s =0 ) , t h e n c l e a r l
| Note t h a t t h i s w i l l r o u n d t o e v e n i n c a s e o f a t i e .
|
rnd_near :
swap % d1 | s e t u p d1 f o r r o u n d p r e c .
asll #1 ,% d0 | s h i f t g - b i t t o c - b i t
bcc t r u n c a t e | i f ( g =1 ) t h e n
lea a d d _ t o _ l ,% a1
movel ( % a1 ,% d1 . w * 4 ) ,% a1
jmp ( % a1 )
|
| ext_ g r s - - - e x t r a c t g u a r d , r o u n d a n d s t i c k y b i t s
|
| Input : d1 = P R E C : R O U N D
| Output : d0 { 3 1 : 2 9 } = g u a r d , r o u n d , s t i c k y
|
| The e x t _ g r s e x t r a c t t h e g u a r d / r o u n d / s t i c k y b i t s a c c o r d i n g t o t h e
| selected r o u n d i n g p r e c i s i o n . I t i s c a l l e d b y t h e r o u n d s u b r o u t i n e
| only. A l l r e g i s t e r s e x c e p t d0 a r e k e p t i n t a c t . d0 b e c o m e s a n
| updated g u a r d ,r o u n d ,s t i c k y i n d0 { 3 1 : 2 9 }
|
| Notes : the e x t _ g r s u s e s t h e r o u n d P R E C , a n d t h e r e f o r e h a s t o s w a p d1
| prior t o u s a g e , a n d n e e d s t o r e s t o r e d1 t o o r i g i n a l .
|
ext_grs :
swap % d1 | h a v e d1 . w p o i n t t o r o u n d p r e c i s i o n
cmpiw #0 ,% d1
bnes s g l _ o r _ d b l
bras e n d _ e x t _ g r s
sgl_or_dbl :
moveml % d2 / % d3 ,- ( % a7 ) | m a k e s o m e t e m p r e g i s t e r s
cmpiw #1 ,% d1
bnes g r s _ d b l
grs_sgl :
bfextu L O C A L _ H I ( % a0 ) { #24 : #2 } ,% d3 | s g l p r e c . g - r a r e 2 b i t s r i g h t
movel #30 ,% d2 | o f t h e s g l p r e c . l i m i t s
lsll % d2 ,% d3 | s h i f t g - r b i t s t o M S B o f d3
movel L O C A L _ H I ( % a0 ) ,% d2 | g e t w o r d 2 f o r s - b i t t e s t
andil #0x0000003f ,% d2 | s b i t i s t h e o r o f a l l o t h e r
bnes s t _ s t k y | b i t s t o t h e r i g h t o f g - r
tstl L O C A L _ L O ( % a0 ) | t e s t l o w e r m a n t i s s a
bnes s t _ s t k y | i f a n y a r e s e t , s e t s t i c k y
tstl % d0 | t e s t o r i g i n a l g ,r ,s
bnes s t _ s t k y | i f a n y a r e s e t , s e t s t i c k y
bras e n d _ s d | i f w o r d s 3 a n d 4 a r e c l r , e x i t
grs_dbl :
bfextu L O C A L _ L O ( % a0 ) { #21 : #2 } ,% d3 | d b l - p r e c . g - r a r e 2 b i t s r i g h t
movel #30 ,% d2 | o f t h e d b l p r e c . l i m i t s
lsll % d2 ,% d3 | s h i f t g - r b i t s t o t h e M S B o f d3
movel L O C A L _ L O ( % a0 ) ,% d2 | g e t l o w e r m a n t i s s a f o r s - b i t t e s t
andil #0x000001ff ,% d2 | s b i t i s t h e o r - i n g o f a l l
bnes s t _ s t k y | o t h e r b i t s t o t h e r i g h t o f g - r
tstl % d0 | t e s t w o r d o r i g i n a l g ,r ,s
bnes s t _ s t k y | i f a n y a r e s e t , s e t s t i c k y
bras e n d _ s d | i f c l e a r , e x i t
st_stky :
bset #r n d _ s t k y _ b i t , % d 3
end_sd :
movel % d3 ,% d0 | r e t u r n g r s t o d0
moveml ( % a7 ) + ,% d2 / % d3 | r e s t o r e s c r a t c h r e g i s t e r s
end_ext_grs :
swap % d1 | r e s t o r e d1 t o o r i g i n a l
rts
| * * * * * * * * * * * * * * * * * * * Local E q u a t e s
.set ad_ 1 _ s g l ,0 x00 0 0 0 1 0 0 | c o n s t a n t t o a d d 1 t o l - b i t i n s g l p r e c
.set ad_ 1 _ d b l ,0 x00 0 0 0 8 0 0 | c o n s t a n t t o a d d 1 t o l - b i t i n d b l p r e c
| Jump t a b l e f o r a d d i n g 1 t o t h e l - b i t i n d e x e d b y r n d p r e c
add_to_l :
.long add_ext
.long add_sgl
.long add_dbl
.long add_dbl
|
| ADD S I N G L E
|
add_sgl :
addl #a d _ 1 _ s g l ,L O C A L _ H I ( % a0 )
bccs s c c _ c l r | n o m a n t i s s a o v e r f l o w
roxrw L O C A L _ H I ( % a0 ) | s h i f t v - b i t b a c k i n
roxrw L O C A L _ H I + 2 ( % a0 ) | s h i f t v - b i t b a c k i n
addw #0x1 ,L O C A L _ E X ( % a0 ) | a n d i n c r e x p o n e n t
scc_clr :
tstl % d0 | t e s t f o r r s = 0
bnes s g l _ d o n e
andiw #0xfe00 ,L O C A L _ H I + 2 ( % a0 ) | c l e a r t h e l - b i t
sgl_done :
andil #0xffffff00 ,L O C A L _ H I ( % a0 ) | t r u n c a t e b i t s b e y o n d s g l l i m i t
clrl L O C A L _ L O ( % a0 ) | c l e a r d2
rts
|
| ADD E X T E N D E D
|
add_ext :
addql #1 ,L O C A L _ L O ( % a0 ) | a d d 1 t o l - b i t
bccs x c c _ c l r | t e s t f o r c a r r y o u t
addql #1 ,L O C A L _ H I ( % a0 ) | p r o p a g a t e c a r r y
bccs x c c _ c l r
roxrw L O C A L _ H I ( % a0 ) | m a n t i s 0 s o r e s t o r e v - b i t
roxrw L O C A L _ H I + 2 ( % a0 ) | m a n t i s 0 s o r e s t o r e v - b i t
roxrw L O C A L _ L O ( % a0 )
roxrw L O C A L _ L O + 2 ( % a0 )
addw #0x1 ,L O C A L _ E X ( % a0 ) | a n d i n c e x p
xcc_clr :
tstl % d0 | t e s t r s = 0
bnes a d d _ e x t _ d o n e
andib #0xfe ,L O C A L _ L O + 3 ( % a0 ) | c l e a r t h e l b i t
add_ext_done :
rts
|
| ADD D O U B L E
|
add_dbl :
addl #a d _ 1 _ d b l ,L O C A L _ L O ( % a0 )
bccs d c c _ c l r
addql #1 ,L O C A L _ H I ( % a0 ) | p r o p a g a t e c a r r y
bccs d c c _ c l r
roxrw L O C A L _ H I ( % a0 ) | m a n t i s 0 s o r e s t o r e v - b i t
roxrw L O C A L _ H I + 2 ( % a0 ) | m a n t i s 0 s o r e s t o r e v - b i t
roxrw L O C A L _ L O ( % a0 )
roxrw L O C A L _ L O + 2 ( % a0 )
addw #0x1 ,L O C A L _ E X ( % a0 ) | i n c r e x p o n e n t
dcc_clr :
tstl % d0 | t e s t f o r r s = 0
bnes d b l _ d o n e
andiw #0xf000 ,L O C A L _ L O + 2 ( % a0 ) | c l e a r t h e l - b i t
dbl_done :
andil #0xfffff800 ,L O C A L _ L O ( % a0 ) | t r u n c a t e b i t s b e y o n d d b l l i m i t
rts
error :
rts
|
| Truncate a l l o t h e r b i t s
|
trunct :
.long end_rnd
.long sgl_done
.long dbl_done
.long dbl_done
truncate :
lea t r u n c t ,% a1
movel ( % a1 ,% d1 . w * 4 ) ,% a1
jmp ( % a1 )
end_rnd :
rts
|
| NORMALIZE
|
| These r o u t i n e s ( n r m _ z e r o & n r m _ s e t ) n o r m a l i z e t h e u n n o r m . T h i s
| is d o n e b y s h i f t i n g t h e m a n t i s s a l e f t w h i l e d e c r e m e n t i n g t h e
| exponent.
|
| NRM_ S E T s h i f t s a n d d e c r e m e n t s u n t i l t h e r e i s a 1 s e t i n t h e i n t e g e r
| bit o f t h e m a n t i s s a ( m s b i n d1 ) .
|
| NRM_ Z E R O s h i f t s a n d d e c r e m e n t s u n t i l t h e r e i s a 1 s e t i n t h e i n t e g e r
| bit o f t h e m a n t i s s a ( m s b i n d1 ) u n l e s s t h i s w o u l d m e a n t h e e x p o n e n t
| would g o l e s s t h a n 0 . I n t h a t c a s e t h e n u m b e r b e c o m e s a d e n o r m - t h e
| exponent ( d0 ) i s s e t t o 0 a n d t h e m a n t i s s a ( d1 & d2 ) i s n o t
| normalized.
|
| Note t h a t b o t h r o u t i n e s h a v e b e e n o p t i m i z e d ( f o r t h e w o r s t c a s e ) a n d
| therefore d o n o t h a v e t h e e a s y t o f o l l o w d e c r e m e n t / s h i f t l o o p .
|
| NRM_ Z E R O
|
| Distance t o f i r s t 1 b i t i n m a n t i s s a = X
| Distance t o 0 f r o m e x p o n e n t = Y
| If X < Y
| Then
| nrm_ s e t
| Else
| shift m a n t i s s a b y Y
| set e x p o n e n t = 0
|
| input :
| FP_ S C R 1 = e x p o n e n t , m s m a n t i s s a p a r t , l s m a n t i s s a p a r t
| output :
| L_ S C R 1 { 4 } = f p t e 1 5 o r e t e 1 5 b i t
|
.global nrm_zero
nrm_zero :
movew L O C A L _ E X ( % a0 ) ,% d0
cmpw #64 ,% d0 | s e e i f e x p > 6 4
bmis d0 _ l e s s
bsr n r m _ s e t | e x p > 6 4 s o e x p w o n ' t e x c e e d 0
rts
d0_less :
moveml % d2 / % d3 / % d5 / % d6 ,- ( % a7 )
movel L O C A L _ H I ( % a0 ) ,% d1
movel L O C A L _ L O ( % a0 ) ,% d2
bfffo % d1 { #0 : #32 } ,% d3 | g e t t h e d i s t a n c e t o t h e f i r s t 1
| ;in ms mant
beqs m s _ c l r | b r a n c h i f n o b i t s w e r e s e t
cmpw % d3 ,% d0 | o f X > Y
bmis g r e a t e r | t h e n e x p w i l l g o p a s t 0 ( n e g ) i f
| ;it is just shifted
bsr n r m _ s e t | e l s e e x p w o n ' t g o p a s t 0
moveml ( % a7 ) + ,% d2 / % d3 / % d5 / % d6
rts
greater :
movel % d2 ,% d6 | s a v e l s m a n t i n d6
lsll % d0 ,% d2 | s h i f t l s m a n t b y c o u n t
lsll % d0 ,% d1 | s h i f t m s m a n t b y c o u n t
movel #32 ,% d5
subl % d0 ,% d5 | m a k e o p a d e n o r m b y s h i f t i n g b i t s
lsrl % d5 ,% d6 | b y t h e n u m b e r i n t h e e x p , t h e n
| ;set exp = 0.
orl % d6 ,% d1 | s h i f t t h e l s m a n t b i t s i n t o t h e m s m a n t
movel #0 ,% d0 | s a m e a s i f d e c r e m e n t e d e x p t o 0
| ;while shifting
movew % d0 ,L O C A L _ E X ( % a0 )
movel % d1 ,L O C A L _ H I ( % a0 )
movel % d2 ,L O C A L _ L O ( % a0 )
moveml ( % a7 ) + ,% d2 / % d3 / % d5 / % d6
rts
ms_clr :
bfffo % d2 { #0 : #32 } ,% d3 | c h e c k i f a n y b i t s s e t i n l s m a n t
beqs a l l _ c l r | b r a n c h i f n o n e s e t
addw #32 ,% d3
cmpw % d3 ,% d0 | i f X > Y
bmis g r e a t e r | t h e n b r a n c h
bsr n r m _ s e t | e l s e e x p w o n ' t g o p a s t 0
moveml ( % a7 ) + ,% d2 / % d3 / % d5 / % d6
rts
all_clr :
movew #0 ,L O C A L _ E X ( % a0 ) | n o m a n t i s s a b i t s s e t . S e t e x p = 0 .
moveml ( % a7 ) + ,% d2 / % d3 / % d5 / % d6
rts
|
| NRM_ S E T
|
.global nrm_set
nrm_set :
movel % d7 ,- ( % a7 )
bfffo L O C A L _ H I ( % a0 ) { #0 : #32 } ,% d7 | f i n d f i r s t 1 i n m s m a n t t o d7 )
beqs l o w e r | b r a n c h i f m s m a n t i s a l l 0 ' s
movel % d6 ,- ( % a7 )
subw % d7 ,L O C A L _ E X ( % a0 ) | s u b e x p o n e n t b y c o u n t
movel L O C A L _ H I ( % a0 ) ,% d0 | d0 h a s m s m a n t
movel L O C A L _ L O ( % a0 ) ,% d1 | d1 h a s l s m a n t
lsll % d7 ,% d0 | s h i f t f i r s t 1 t o j b i t p o s i t i o n
movel % d1 ,% d6 | c o p y l s m a n t i n t o d6
lsll % d7 ,% d6 | s h i f t l s m a n t b y c o u n t
movel % d6 ,L O C A L _ L O ( % a0 ) | s t o r e l s m a n t i n t o m e m o r y
moveql #32 ,% d6
subl % d7 ,% d6 | c o n t i n u e s h i f t
lsrl % d6 ,% d1 | s h i f t o f f a l l b i t s b u t t h o s e t h a t w i l l
| ;be shifted into ms mant
orl % d1 ,% d0 | s h i f t t h e l s m a n t b i t s i n t o t h e m s m a n t
movel % d0 ,L O C A L _ H I ( % a0 ) | s t o r e m s m a n t i n t o m e m o r y
moveml ( % a7 ) + ,% d7 / % d6 | r e s t o r e r e g i s t e r s
rts
|
| We g e t h e r e i f m s m a n t w a s = 0 , a n d w e a s s u m e l s m a n t h a s b i t s
| set ( o t h e r w i s e t h i s w o u l d h a v e b e e n t a g g e d a z e r o n o t a d e n o r m ) .
|
lower :
movew L O C A L _ E X ( % a0 ) ,% d0 | d0 h a s e x p o n e n t
movel L O C A L _ L O ( % a0 ) ,% d1 | d1 h a s l s m a n t
subw #32 ,% d0 | a c c o u n t f o r m s m a n t b e i n g a l l z e r o s
bfffo % d1 { #0 : #32 } ,% d7 | f i n d f i r s t 1 i n l s m a n t t o d7 )
subw % d7 ,% d0 | s u b t r a c t s h i f t c o u n t f r o m e x p
lsll % d7 ,% d1 | s h i f t f i r s t 1 t o i n t e g e r b i t i n m s m a n t
movew % d0 ,L O C A L _ E X ( % a0 ) | s t o r e m s m a n t
movel % d1 ,L O C A L _ H I ( % a0 ) | s t o r e e x p
clrl L O C A L _ L O ( % a0 ) | c l e a r l s m a n t
movel ( % a7 ) + ,% d7
rts
|
| denorm - - - d e n o r m a l i z e a n i n t e r m e d i a t e r e s u l t
|
| Used b y u n d e r f l o w .
|
| Input :
| a0 p o i n t s t o t h e o p e r a n d t o b e d e n o r m a l i z e d
| ( in t h e i n t e r n a l e x t e n d e d f o r m a t )
|
| d0 : rounding p r e c i s i o n
| Output :
| a0 p o i n t s t o t h e d e n o r m a l i z e d r e s u l t
| ( in t h e i n t e r n a l e x t e n d e d f o r m a t )
|
| d0 i s g u a r d ,r o u n d ,s t i c k y
|
| d0 c o m e s i n t o t h i s r o u t i n e w i t h t h e r o u n d i n g p r e c i s i o n . I t
| is t h e n l o a d e d w i t h t h e d e n o r m a l i z e d e x p o n e n t t h r e s h o l d f o r t h e
| rounding p r e c i s i o n .
|
.global denorm
denorm :
btstb #6 ,L O C A L _ E X ( % a0 ) | c h e c k f o r e x p o n e n t s b e t w e e n $ 7 f f f - $ 4 0 0 0
beqs n o _ s g n _ e x t
bsetb #7 ,L O C A L _ E X ( % a0 ) | s i g n e x t e n d i f i t i s s o
no_sgn_ext :
cmpib #0 ,% d0 | i f 0 t h e n e x t e n d e d p r e c i s i o n
bnes n o t _ e x t | e l s e b r a n c h
clrl % d1 | l o a d d1 w i t h e x t t h r e s h o l d
clrl % d0 | c l e a r t h e s t i c k y f l a g
bsr d n r m _ l p | d e n o r m a l i z e t h e n u m b e r
tstb % d1 | c h e c k f o r i n e x
beq n o _ i n e x | i f c l r , n o i n e x
bras d n r m _ i n e x | i f s e t , s e t i n e x
not_ext :
cmpil #1 ,% d0 | i f 1 t h e n s i n g l e p r e c i s i o n
beqs l o a d _ s g l | e l s e m u s t b e 2 , d o u b l e p r e c
load_dbl :
movew #d b l _ t h r e s h , % d 1 | p u t c o p y o f t h r e s h o l d i n d1
movel % d1 ,% d0 | c o p y d1 i n t o d0
subw L O C A L _ E X ( % a0 ) ,% d0 | d i f f = t h r e s h o l d - e x p
cmpw #67 ,% d0 | i f d i f f > 6 7 ( m a n t + g r s b i t s )
bpls c h k _ s t k y | t h e n b r a n c h ( a l l b i t s w o u l d b e
| ; shifted off in denorm routine)
clrl % d0 | e l s e c l e a r t h e s t i c k y f l a g
bsr d n r m _ l p | d e n o r m a l i z e t h e n u m b e r
tstb % d1 | c h e c k f l a g
beqs n o _ i n e x | i f c l r , n o i n e x
bras d n r m _ i n e x | i f s e t , s e t i n e x
load_sgl :
movew #s g l _ t h r e s h , % d 1 | p u t c o p y o f t h r e s h o l d i n d1
movel % d1 ,% d0 | c o p y d1 i n t o d0
subw L O C A L _ E X ( % a0 ) ,% d0 | d i f f = t h r e s h o l d - e x p
cmpw #67 ,% d0 | i f d i f f > 6 7 ( m a n t + g r s b i t s )
bpls c h k _ s t k y | t h e n b r a n c h ( a l l b i t s w o u l d b e
| ; shifted off in denorm routine)
clrl % d0 | e l s e c l e a r t h e s t i c k y f l a g
bsr d n r m _ l p | d e n o r m a l i z e t h e n u m b e r
tstb % d1 | c h e c k f l a g
beqs n o _ i n e x | i f c l r , n o i n e x
bras d n r m _ i n e x | i f s e t , s e t i n e x
chk_stky :
tstl L O C A L _ H I ( % a0 ) | c h e c k f o r a n y b i t s s e t
bnes s e t _ s t k y
tstl L O C A L _ L O ( % a0 ) | c h e c k f o r a n y b i t s s e t
bnes s e t _ s t k y
bras c l r _ m a n t
set_stky :
orl #i n x 2 a _ m a s k ,U S E R _ F P S R ( % a6 ) | s e t i n e x2 / a i n e x
movel #0x20000000 ,% d0 | s e t s t i c k y b i t i n r e t u r n v a l u e
clr_mant :
movew % d1 ,L O C A L _ E X ( % a0 ) | l o a d e x p w i t h t h r e s h o l d
movel #0 ,L O C A L _ H I ( % a0 ) | s e t d1 = 0 ( m s m a n t i s s a )
movel #0 ,L O C A L _ L O ( % a0 ) | s e t d2 = 0 ( m s m a n t i s s a )
rts
dnrm_inex :
orl #i n x 2 a _ m a s k ,U S E R _ F P S R ( % a6 ) | s e t i n e x2 / a i n e x
no_inex :
rts
|
| dnrm_ l p - - - n o r m a l i z e e x p o n e n t / m a n t i s s a t o s p e c i f i e d t h r e s h o l d
|
| Input :
| a0 p o i n t s t o t h e o p e r a n d t o b e d e n o r m a l i z e d
| d0 { 3 1 : 2 9 } i n i t i a l g u a r d ,r o u n d ,s t i c k y
| d1 { 1 5 : 0 } d e n o r m a l i z a t i o n t h r e s h o l d
| Output :
| a0 p o i n t s t o t h e d e n o r m a l i z e d o p e r a n d
| d0 { 3 1 : 2 9 } f i n a l g u a r d ,r o u n d ,s t i c k y
| d1 . b i n e x a c t f l a g : a l l o n e s m e a n s i n e x a c t r e s u l t
|
| The L O C A L _ L O a n d L O C A L _ G R S p a r t s o f t h e v a l u e a r e c o p i e d t o F P _ S C R 2
| so t h a t b f e x t c a n b e u s e d t o e x t r a c t t h e n e w l o w p a r t o f t h e m a n t i s s a .
| Dnrm_ l p c a n b e c a l l e d w i t h a0 p o i n t i n g t o E T E M P o r W B T E M P a n d t h e r e
| is n o L O C A L _ G R S s c r a t c h w o r d f o l l o w i n g i t o n t h e f s a v e f r a m e .
|
.global dnrm_lp
dnrm_lp :
movel % d2 ,- ( % s p ) | s a v e d2 f o r t e m p u s e
btstb #E 3 ,E _ B Y T E ( % a6 ) | t e s t f o r t y p e E 3 e x c e p t i o n
beqs n o t _ E 3 | n o t t y p e E 3 e x c e p t i o n
bfextu W B T E M P _ G R S ( % a6 ) { #6 : #3 } ,% d2 | e x t r a c t g u a r d ,r o u n d , s t i c k y b i t
movel #29 ,% d0
lsll % d0 ,% d2 | s h i f t g ,r ,s t o t h e i r p o s i t i o n s
movel % d2 ,% d0
not_E3 :
movel ( % s p ) + ,% d2 | r e s t o r e d2
movel L O C A L _ L O ( % a0 ) ,F P _ S C R 2 + L O C A L _ L O ( % a6 )
movel % d0 ,F P _ S C R 2 + L O C A L _ G R S ( % a6 )
movel % d1 ,% d0 | c o p y t h e d e n o r m t h r e s h o l d
subw L O C A L _ E X ( % a0 ) ,% d1 | d1 = t h r e s h o l d - u n s e x p o n e n t
bles n o _ l p | d1 < = 0
cmpw #32 ,% d1
blts c a s e _ 1 | 0 = d1 < 3 2
cmpw #64 ,% d1
blts c a s e _ 2 | 3 2 < = d1 < 6 4
bra c a s e _ 3 | d1 > = 6 4
|
| No n o r m a l i z a t i o n n e c e s s a r y
|
no_lp :
clrb % d1 | s e t n o i n e x2 r e p o r t e d
movel F P _ S C R 2 + L O C A L _ G R S ( % a6 ) ,% d0 | r e s t o r e o r i g i n a l g ,r ,s
rts
|
| case ( 0 < d1 < 3 2 )
|
case_1 :
movel % d2 ,- ( % s p )
movew % d0 ,L O C A L _ E X ( % a0 ) | e x p o n e n t = d e n o r m t h r e s h o l d
movel #32 ,% d0
subw % d1 ,% d0 | d0 = 3 2 - d1
bfextu L O C A L _ E X ( % a0 ) { % d0 : #32 } ,% d2
bfextu % d2 { % d1 : % d0 } ,% d2 | d2 = n e w L O C A L _ H I
bfextu L O C A L _ H I ( % a0 ) { % d0 : #32 } ,% d1 | d1 = n e w L O C A L _ L O
bfextu F P _ S C R 2 + L O C A L _ L O ( % a6 ) { % d0 : #32 } ,% d0 | d0 = n e w G ,R ,S
movel % d2 ,L O C A L _ H I ( % a0 ) | s t o r e n e w L O C A L _ H I
movel % d1 ,L O C A L _ L O ( % a0 ) | s t o r e n e w L O C A L _ L O
clrb % d1
bftst % d0 { #2 : #30 }
beqs c1 n s t k y
bsetl #r n d _ s t k y _ b i t , % d 0
st % d1
c1nstky :
movel F P _ S C R 2 + L O C A L _ G R S ( % a6 ) ,% d2 | r e s t o r e o r i g i n a l g ,r ,s
andil #0xe0000000 ,% d2 | c l e a r a l l b u t G ,R ,S
tstl % d2 | t e s t i f o r i g i n a l G ,R ,S a r e c l e a r
beqs g r s _ c l e a r
orl #0x20000000 ,% d0 | s e t s t i c k y b i t i n d0
grs_clear :
andil #0xe0000000 ,% d0 | c l e a r a l l b u t G ,R ,S
movel ( % s p ) + ,% d2
rts
|
| case ( 3 2 < =d1 < 6 4 )
|
case_2 :
movel % d2 ,- ( % s p )
movew % d0 ,L O C A L _ E X ( % a0 ) | u n s i g n e d e x p o n e n t = t h r e s h o l d
subw #32 ,% d1 | d1 n o w b e t w e e n 0 a n d 3 2
movel #32 ,% d0
subw % d1 ,% d0 | d0 = 3 2 - d1
bfextu L O C A L _ E X ( % a0 ) { % d0 : #32 } ,% d2
bfextu % d2 { % d1 : % d0 } ,% d2 | d2 = n e w L O C A L _ L O
bfextu L O C A L _ H I ( % a0 ) { % d0 : #32 } ,% d1 | d1 = n e w G ,R ,S
bftst % d1 { #2 : #30 }
bnes c2 _ s s t k y | b r a i f s t i c k y b i t t o b e s e t
bftst F P _ S C R 2 + L O C A L _ L O ( % a6 ) { % d0 : #32 }
bnes c2 _ s s t k y | b r a i f s t i c k y b i t t o b e s e t
movel % d1 ,% d0
clrb % d1
bras e n d _ c2
c2_sstky :
movel % d1 ,% d0
bsetl #r n d _ s t k y _ b i t , % d 0
st % d1
end_c2 :
clrl L O C A L _ H I ( % a0 ) | s t o r e L O C A L _ H I = 0
movel % d2 ,L O C A L _ L O ( % a0 ) | s t o r e L O C A L _ L O
movel F P _ S C R 2 + L O C A L _ G R S ( % a6 ) ,% d2 | r e s t o r e o r i g i n a l g ,r ,s
andil #0xe0000000 ,% d2 | c l e a r a l l b u t G ,R ,S
tstl % d2 | t e s t i f o r i g i n a l G ,R ,S a r e c l e a r
beqs c l e a r _ g r s
orl #0x20000000 ,% d0 | s e t s t i c k y b i t i n d0
clear_grs :
andil #0xe0000000 ,% d0 | g e t r i d o f a l l b u t G ,R ,S
movel ( % s p ) + ,% d2
rts
|
| d1 > = 6 4 F o r c e t h e e x p o n e n t t o b e t h e d e n o r m t h r e s h o l d w i t h t h e
| correct s i g n .
|
case_3 :
movew % d0 ,L O C A L _ E X ( % a0 )
tstw L O C A L _ S G N ( % a0 )
bges c3 c o n
c3neg :
orl #0x80000000 ,L O C A L _ E X ( % a0 )
c3con :
cmpw #64 ,% d1
beqs s i x t y _ f o u r
cmpw #65 ,% d1
beqs s i x t y _ f i v e
|
| Shift v a l u e i s o u t o f r a n g e . S e t d1 f o r i n e x2 f l a g a n d
| return a z e r o w i t h t h e g i v e n t h r e s h o l d .
|
clrl L O C A L _ H I ( % a0 )
clrl L O C A L _ L O ( % a0 )
movel #0x20000000 ,% d0
st % d1
rts
sixty_four :
movel L O C A L _ H I ( % a0 ) ,% d0
bfextu % d0 { #2 : #30 } ,% d1
andil #0xc0000000 ,% d0
bras c3 c o m
sixty_five :
movel L O C A L _ H I ( % a0 ) ,% d0
bfextu % d0 { #1 : #31 } ,% d1
andil #0x80000000 ,% d0
lsrl #1 ,% d0 | s h i f t h i g h b i t i n t o R b i t
c3com :
tstl % d1
bnes c3 s s t i c k y
tstl L O C A L _ L O ( % a0 )
bnes c3 s s t i c k y
tstb F P _ S C R 2 + L O C A L _ G R S ( % a6 )
bnes c3 s s t i c k y
clrb % d1
bras c3 e n d
c3ssticky :
bsetl #r n d _ s t k y _ b i t , % d 0
st % d1
c3end :
clrl L O C A L _ H I ( % a0 )
clrl L O C A L _ L O ( % a0 )
rts
| end