2005-04-16 15:20:36 -07:00
.file " reg_ u _ a d d . S "
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| reg_ u _ a d d . S |
| |
| Add t w o v a l i d ( T A G _ V a l i d ) F P U _ R E G n u m b e r s , o f t h e s a m e s i g n , a n d p u t t h e |
| result i n a d e s t i n a t i o n F P U _ R E G . |
| |
| Copyright ( C ) 1 9 9 2 ,1 9 9 3 ,1 9 9 5 ,1 9 9 7 |
| W. M e t z e n t h e n , 2 2 P a r k e r S t , O r m o n d , V i c 3 1 6 3 , A u s t r a l i a |
| E- m a i l b i l l m @suburbia.net |
| |
| Call f r o m C a s : |
| int F P U _ u _ a d d ( F P U _ R E G * a r g 1 , F P U _ R E G * a r g 2 , F P U _ R E G * a n s w , |
| int c o n t r o l _ w ) |
| Return v a l u e i s t h e t a g o f t h e a n s w e r , o r - e d w i t h F P U _ E x c e p t i o n i f |
| one w a s r a i s e d , o r - 1 o n i n t e r n a l e r r o r . |
| |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * /
/ *
| Kernel a d d i t i o n r o u t i n e F P U _ u _ a d d ( r e g * a r g 1 , r e g * a r g 2 , r e g * a n s w ) .
| Takes t w o v a l i d r e g f . p . n u m b e r s ( T A G _ V a l i d ) , w h i c h a r e
| treated a s u n s i g n e d n u m b e r s ,
| and r e t u r n s t h e i r s u m a s a T A G _ V a l i d o r T A G _ S p e c i a l f . p . n u m b e r .
| The r e t u r n e d n u m b e r i s n o r m a l i z e d .
| Basic c h e c k s a r e p e r f o r m e d i f P A R A N O I D i s d e f i n e d .
* /
# include " e x c e p t i o n . h "
# include " f p u _ e m u . h "
# include " c o n t r o l _ w . h "
.text
ENTRY( F P U _ u _ a d d )
pushl % e b p
movl % e s p ,% e b p
pushl % e s i
pushl % e d i
pushl % e b x
movl P A R A M 1 ,% e s i / * s o u r c e 1 * /
movl P A R A M 2 ,% e d i / * s o u r c e 2 * /
movl P A R A M 6 ,% e c x
movl % e c x ,% e d x
subl P A R A M 7 ,% e c x / * e x p1 - e x p2 * /
jge L _ a r g 1 _ l a r g e r
/* num1 is smaller */
movl S I G L ( % e s i ) ,% e b x
movl S I G H ( % e s i ) ,% e a x
movl % e d i ,% e s i
movl P A R A M 7 ,% e d x
negw % c x
jmp L _ a c c u m _ l o a d e d
L_arg1_larger :
/* num1 has larger or equal exponent */
movl S I G L ( % e d i ) ,% e b x
movl S I G H ( % e d i ) ,% e a x
L_accum_loaded :
movl P A R A M 3 ,% e d i / * d e s t i n a t i o n * /
movw % d x ,E X P ( % e d i ) / * C o p y e x p o n e n t t o d e s t i n a t i o n * /
xorl % e d x ,% e d x / * c l e a r t h e e x t e n s i o n * /
# ifdef P A R A N O I D
testl $ 0 x80 0 0 0 0 0 0 ,% e a x
je L _ b u g g e d
testl $ 0 x80 0 0 0 0 0 0 ,S I G H ( % e s i )
je L _ b u g g e d
# endif / * P A R A N O I D * /
/* The number to be shifted is in %eax:%ebx:%edx */
cmpw $ 3 2 ,% c x / * s h r d o n l y w o r k s f o r 0 . . 3 1 b i t s * /
jnc L _ m o r e _ t h a n _ 3 1
/* less than 32 bits */
shrd % c l ,% e b x ,% e d x
shrd % c l ,% e a x ,% e b x
shr % c l ,% e a x
jmp L _ s h i f t _ d o n e
L_more_than_31 :
cmpw $ 6 4 ,% c x
jnc L _ m o r e _ t h a n _ 6 3
subb $ 3 2 ,% c l
jz L _ e x a c t l y _ 3 2
shrd % c l ,% e a x ,% e d x
shr % c l ,% e a x
orl % e b x ,% e b x
jz L _ m o r e _ 3 1 _ n o _ l o w / * n o n e o f t h e l o w e s t b i t s i s s e t * /
orl $ 1 ,% e d x / * r e c o r d t h e f a c t i n t h e e x t e n s i o n * /
L_more_31_no_low :
movl % e a x ,% e b x
xorl % e a x ,% e a x
jmp L _ s h i f t _ d o n e
L_exactly_32 :
movl % e b x ,% e d x
movl % e a x ,% e b x
xorl % e a x ,% e a x
jmp L _ s h i f t _ d o n e
L_more_than_63 :
cmpw $ 6 5 ,% c x
jnc L _ m o r e _ t h a n _ 6 4
movl % e a x ,% e d x
orl % e b x ,% e b x
jz L _ m o r e _ 6 3 _ n o _ l o w
orl $ 1 ,% e d x
jmp L _ m o r e _ 6 3 _ n o _ l o w
L_more_than_64 :
movl $ 1 ,% e d x / * T h e s h i f t e d n r a l w a y s a t l e a s t o n e ' 1 ' * /
L_more_63_no_low :
xorl % e b x ,% e b x
xorl % e a x ,% e a x
L_shift_done :
/* Now do the addition */
addl S I G L ( % e s i ) ,% e b x
adcl S I G H ( % e s i ) ,% e a x
jnc L _ r o u n d _ t h e _ r e s u l t
/* Overflow, adjust the result */
rcrl $ 1 ,% e a x
rcrl $ 1 ,% e b x
rcrl $ 1 ,% e d x
jnc L _ n o _ b i t _ l o s t
orl $ 1 ,% e d x
L_no_bit_lost :
incw E X P ( % e d i )
L_round_the_result :
jmp f p u _ r e g _ r o u n d / * R o u n d t h e r e s u l t * /
# ifdef P A R A N O I D
/* If we ever get here then we have problems! */
L_bugged :
pushl E X _ I N T E R N A L | 0 x20 1
call E X C E P T I O N
pop % e b x
movl $ - 1 ,% e a x
jmp L _ e x i t
L_exit :
popl % e b x
popl % e d i
popl % e s i
leave
ret
# endif / * P A R A N O I D * /
2017-08-24 10:06:23 +02:00
ENDPROC( F P U _ u _ a d d )