2005-04-17 02:20:36 +04:00
/ *
* fp_ e m u . S
*
* Copyright R o m a n Z i p p e l , 1 9 9 7 . A l l r i g h t s r e s e r v e d .
*
* Redistribution a n d u s e i n s o u r c e a n d b i n a r y f o r m s , w i t h o r w i t h o u t
* modification, a r e p e r m i t t e d p r o v i d e d t h a t t h e f o l l o w i n g c o n d i t i o n s
* are m e t :
* 1 . Redistributions o f s o u r c e c o d e m u s t r e t a i n t h e a b o v e c o p y r i g h t
* notice, a n d t h e e n t i r e p e r m i s s i o n n o t i c e i n i t s e n t i r e t y ,
* including t h e d i s c l a i m e r o f w a r r a n t i e s .
* 2 . Redistributions i n b i n a r y f o r m m u s t r e p r o d u c e t h e a b o v e c o p y r i g h t
* notice, t h i s l i s t o f c o n d i t i o n s a n d t h e f o l l o w i n g d i s c l a i m e r i n t h e
* documentation a n d / o r o t h e r m a t e r i a l s p r o v i d e d w i t h t h e d i s t r i b u t i o n .
* 3 . The n a m e o f t h e a u t h o r m a y n o t b e u s e d t o e n d o r s e o r p r o m o t e
* products d e r i v e d f r o m t h i s s o f t w a r e w i t h o u t s p e c i f i c p r i o r
* written p e r m i s s i o n .
*
* ALTERNATIVELY, t h i s p r o d u c t m a y b e d i s t r i b u t e d u n d e r t h e t e r m s o f
* the G N U G e n e r a l P u b l i c L i c e n s e , i n w h i c h c a s e t h e p r o v i s i o n s o f t h e G P L a r e
* required I N S T E A D O F t h e a b o v e r e s t r i c t i o n s . ( T h i s c l a u s e i s
* necessary d u e t o a p o t e n t i a l b a d i n t e r a c t i o n b e t w e e n t h e G P L a n d
* the r e s t r i c t i o n s c o n t a i n e d i n a B S D - s t y l e c o p y r i g h t . )
*
* THIS S O F T W A R E I S P R O V I D E D ` ` A S I S ' ' A N D A N Y E X P R E S S O R I M P L I E D
* WARRANTIES, I N C L U D I N G , B U T N O T L I M I T E D T O , T H E I M P L I E D W A R R A N T I E S
* OF M E R C H A N T A B I L I T Y A N D F I T N E S S F O R A P A R T I C U L A R P U R P O S E A R E
* DISCLAIMED. I N N O E V E N T S H A L L T H E A U T H O R B E L I A B L E F O R A N Y D I R E C T ,
* INDIRECT, I N C I D E N T A L , S P E C I A L , E X E M P L A R Y , O R C O N S E Q U E N T I A L D A M A G E S
* ( INCLUDING, B U T N O T L I M I T E D T O , P R O C U R E M E N T O F S U B S T I T U T E G O O D S O R
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER C A U S E D A N D O N A N Y T H E O R Y O F L I A B I L I T Y , W H E T H E R I N C O N T R A C T ,
* STRICT L I A B I L I T Y , O R T O R T ( I N C L U D I N G N E G L I G E N C E O R O T H E R W I S E )
* ARISING I N A N Y W A Y O U T O F T H E U S E O F T H I S S O F T W A R E , E V E N I F A D V I S E D
* OF T H E P O S S I B I L I T Y O F S U C H D A M A G E .
* /
# include < l i n u x / l i n k a g e . h >
# include < a s m / e n t r y . h >
# include " f p _ e m u . h "
.globl fpu_emu
.globl fp_debugprint
.globl fp_ e r r _ u a1 ,f p _ e r r _ u a2
.text
fpu_emu :
SAVE_ A L L _ I N T
GET_ C U R R E N T ( % d0 )
# if d e f i n e d ( C P U _ M 6 8 0 2 0 _ O R _ M 6 8 0 3 0 ) & & d e f i n e d ( C P U _ M 6 8 0 4 0 _ O R _ M 6 8 0 6 0 )
tst. l m 6 8 k _ i s04 0 o r06 0
jeq 1 f
# endif
# if d e f i n e d ( C P U _ M 6 8 0 4 0 _ O R _ M 6 8 0 6 0 )
move. l ( F P S _ P C 2 ,% s p ) ,( F P S _ P C ,% s p )
# endif
1 :
| emulate t h e i n s t r u c t i o n
jsr f p _ s c a n
# if d e f i n e d ( C O N F I G _ M 6 8 0 6 0 )
# if ! d e f i n e d ( C P U _ M 6 8 0 6 0 _ O N L Y )
btst #3 ,m 6 8 k _ c p u t y p e + 3
jeq 1 f
# endif
btst #7 ,( F P S _ S R ,% s p )
jne f p _ s e n d t r a c e 0 6 0
# endif
1 :
| emulation s u c c e s s f u l ?
tst. l % d0
jeq r e t _ f r o m _ e x c e p t i o n
| send s o m e s i g n a l t o p r o g r a m h e r e
jra r e t _ f r o m _ e x c e p t i o n
| we j u m p h e r e a f t e r a n a c c e s s e r r o r w h i l e t r y i n g t o a c c e s s
| user s p a c e , w e c o r r e c t s t a c k p o i n t e r a n d s e n d a S I G S E G V t o
| the u s e r p r o c e s s
fp_err_ua2 :
addq. l #4 ,% s p
fp_err_ua1 :
addq. l #4 ,% s p
move. l % a0 ,- ( % s p )
2009-08-31 16:43:34 +04:00
pea L S E G V _ M A P E R R
pea L S I G S E G V
2005-04-17 02:20:36 +04:00
jsr f p e m u _ s i g n a l
add. w #12 ,% s p
jra r e t _ f r o m _ e x c e p t i o n
# if d e f i n e d ( C O N F I G _ M 6 8 0 6 0 )
| send a t r a c e s i g n a l i f w e a r e d e b u g g e d
| it d o e s n o t r e a l l y b e l o n g h e r e , b u t . . .
fp_sendtrace060 :
move. l ( F P S _ P C ,% s p ) ,- ( % s p )
2009-08-31 16:43:34 +04:00
pea L T R A P _ T R A C E
pea L S I G T R A P
2005-04-17 02:20:36 +04:00
jsr f p e m u _ s i g n a l
add. w #12 ,% s p
jra r e t _ f r o m _ e x c e p t i o n
# endif
.globl fp_ g e t _ d a t a _ r e g , f p _ p u t _ d a t a _ r e g
.globl fp_ g e t _ a d d r _ r e g , f p _ p u t _ a d d r _ r e g
| Entry p o i n t s t o g e t / p u t a r e g i s t e r . S o m e o f t h e m c a n b e g e t / p u t
| directly, o t h e r s a r e o n t h e s t a c k , a s w e r e a d / w r i t e t h e s t a c k
| directly h e r e , t h e s e f u n c t i o n m a y o n l y b e c a l l e d f r o m w i t h i n
| instruction d e c o d i n g , o t h e r w i s e t h e s t a c k p o i n t e r i s i n c o r r e c t
| and t h e s t a c k g e t s c o r r u p t e d .
fp_get_data_reg :
jmp ( [ 0 f : w ,% p c ,% d0 . w * 4 ] )
.align 4
0 :
.long fp_ g e t _ d0 , f p _ g e t _ d1
.long fp_ g e t _ d2 , f p _ g e t _ d3
.long fp_ g e t _ d4 , f p _ g e t _ d5
.long fp_ g e t _ d6 , f p _ g e t _ d7
fp_get_d0 :
2009-08-31 16:43:33 +04:00
move. l ( P T _ O F F _ D 0 + 8 ,% s p ) ,% d0
2005-04-17 02:20:36 +04:00
printf P R E G I S T E R ," { d0 - > % 0 8 x } " ,1 ,% d0
rts
fp_get_d1 :
2009-08-31 16:43:33 +04:00
move. l ( P T _ O F F _ D 1 + 8 ,% s p ) ,% d0
2005-04-17 02:20:36 +04:00
printf P R E G I S T E R ," { d1 - > % 0 8 x } " ,1 ,% d0
rts
fp_get_d2 :
2009-08-31 16:43:33 +04:00
move. l ( P T _ O F F _ D 2 + 8 ,% s p ) ,% d0
2005-04-17 02:20:36 +04:00
printf P R E G I S T E R ," { d2 - > % 0 8 x } " ,1 ,% d0
rts
fp_get_d3 :
move. l % d3 ,% d0
printf P R E G I S T E R ," { d3 - > % 0 8 x } " ,1 ,% d0
rts
fp_get_d4 :
move. l % d4 ,% d0
printf P R E G I S T E R ," { d4 - > % 0 8 x } " ,1 ,% d0
rts
fp_get_d5 :
move. l % d5 ,% d0
printf P R E G I S T E R ," { d5 - > % 0 8 x } " ,1 ,% d0
rts
fp_get_d6 :
move. l % d6 ,% d0
printf P R E G I S T E R ," { d6 - > % 0 8 x } " ,1 ,% d0
rts
fp_get_d7 :
move. l % d7 ,% d0
printf P R E G I S T E R ," { d7 - > % 0 8 x } " ,1 ,% d0
rts
fp_put_data_reg :
jmp ( [ 0 f : w ,% p c ,% d1 . w * 4 ] )
.align 4
0 :
.long fp_ p u t _ d0 , f p _ p u t _ d1
.long fp_ p u t _ d2 , f p _ p u t _ d3
.long fp_ p u t _ d4 , f p _ p u t _ d5
.long fp_ p u t _ d6 , f p _ p u t _ d7
fp_put_d0 :
printf P R E G I S T E R ," { d0 < - % 0 8 x } " ,1 ,% d0
2009-08-31 16:43:33 +04:00
move. l % d0 ,( P T _ O F F _ D 0 + 8 ,% s p )
2005-04-17 02:20:36 +04:00
rts
fp_put_d1 :
printf P R E G I S T E R ," { d1 < - % 0 8 x } " ,1 ,% d0
2009-08-31 16:43:33 +04:00
move. l % d0 ,( P T _ O F F _ D 1 + 8 ,% s p )
2005-04-17 02:20:36 +04:00
rts
fp_put_d2 :
printf P R E G I S T E R ," { d2 < - % 0 8 x } " ,1 ,% d0
2009-08-31 16:43:33 +04:00
move. l % d0 ,( P T _ O F F _ D 2 + 8 ,% s p )
2005-04-17 02:20:36 +04:00
rts
fp_put_d3 :
printf P R E G I S T E R ," { d3 < - % 0 8 x } " ,1 ,% d0
| move. l % d0 ,% d3
2009-08-31 16:43:33 +04:00
move. l % d0 ,( P T _ O F F _ D 3 + 8 ,% s p )
2005-04-17 02:20:36 +04:00
rts
fp_put_d4 :
printf P R E G I S T E R ," { d4 < - % 0 8 x } " ,1 ,% d0
| move. l % d0 ,% d4
2009-08-31 16:43:33 +04:00
move. l % d0 ,( P T _ O F F _ D 4 + 8 ,% s p )
2005-04-17 02:20:36 +04:00
rts
fp_put_d5 :
printf P R E G I S T E R ," { d5 < - % 0 8 x } " ,1 ,% d0
| move. l % d0 ,% d5
2009-08-31 16:43:33 +04:00
move. l % d0 ,( P T _ O F F _ D 5 + 8 ,% s p )
2005-04-17 02:20:36 +04:00
rts
fp_put_d6 :
printf P R E G I S T E R ," { d6 < - % 0 8 x } " ,1 ,% d0
move. l % d0 ,% d6
rts
fp_put_d7 :
printf P R E G I S T E R ," { d7 < - % 0 8 x } " ,1 ,% d0
move. l % d0 ,% d7
rts
fp_get_addr_reg :
jmp ( [ 0 f : w ,% p c ,% d0 . w * 4 ] )
.align 4
0 :
.long fp_ g e t _ a0 , f p _ g e t _ a1
.long fp_ g e t _ a2 , f p _ g e t _ a3
.long fp_ g e t _ a4 , f p _ g e t _ a5
.long fp_ g e t _ a6 , f p _ g e t _ a7
fp_get_a0 :
2009-08-31 16:43:33 +04:00
move. l ( P T _ O F F _ A 0 + 8 ,% s p ) ,% a0
2005-04-17 02:20:36 +04:00
printf P R E G I S T E R ," { a0 - > % 0 8 x } " ,1 ,% a0
rts
fp_get_a1 :
2009-08-31 16:43:33 +04:00
move. l ( P T _ O F F _ A 1 + 8 ,% s p ) ,% a0
2005-04-17 02:20:36 +04:00
printf P R E G I S T E R ," { a1 - > % 0 8 x } " ,1 ,% a0
rts
fp_get_a2 :
2009-08-31 16:43:33 +04:00
move. l ( P T _ O F F _ A 2 + 8 ,% s p ) ,% a0
2005-04-17 02:20:36 +04:00
printf P R E G I S T E R ," { a2 - > % 0 8 x } " ,1 ,% a0
rts
fp_get_a3 :
move. l % a3 ,% a0
printf P R E G I S T E R ," { a3 - > % 0 8 x } " ,1 ,% a0
rts
fp_get_a4 :
move. l % a4 ,% a0
printf P R E G I S T E R ," { a4 - > % 0 8 x } " ,1 ,% a0
rts
fp_get_a5 :
move. l % a5 ,% a0
printf P R E G I S T E R ," { a5 - > % 0 8 x } " ,1 ,% a0
rts
fp_get_a6 :
move. l % a6 ,% a0
printf P R E G I S T E R ," { a6 - > % 0 8 x } " ,1 ,% a0
rts
fp_get_a7 :
move. l % u s p ,% a0
printf P R E G I S T E R ," { a7 - > % 0 8 x } " ,1 ,% a0
rts
fp_put_addr_reg :
jmp ( [ 0 f : w ,% p c ,% d0 . w * 4 ] )
.align 4
0 :
.long fp_ p u t _ a0 , f p _ p u t _ a1
.long fp_ p u t _ a2 , f p _ p u t _ a3
.long fp_ p u t _ a4 , f p _ p u t _ a5
.long fp_ p u t _ a6 , f p _ p u t _ a7
fp_put_a0 :
printf P R E G I S T E R ," { a0 < - % 0 8 x } " ,1 ,% a0
2009-08-31 16:43:33 +04:00
move. l % a0 ,( P T _ O F F _ A 0 + 8 ,% s p )
2005-04-17 02:20:36 +04:00
rts
fp_put_a1 :
printf P R E G I S T E R ," { a1 < - % 0 8 x } " ,1 ,% a0
2009-08-31 16:43:33 +04:00
move. l % a0 ,( P T _ O F F _ A 1 + 8 ,% s p )
2005-04-17 02:20:36 +04:00
rts
fp_put_a2 :
printf P R E G I S T E R ," { a2 < - % 0 8 x } " ,1 ,% a0
2009-08-31 16:43:33 +04:00
move. l % a0 ,( P T _ O F F _ A 2 + 8 ,% s p )
2005-04-17 02:20:36 +04:00
rts
fp_put_a3 :
printf P R E G I S T E R ," { a3 < - % 0 8 x } " ,1 ,% a0
move. l % a0 ,% a3
rts
fp_put_a4 :
printf P R E G I S T E R ," { a4 < - % 0 8 x } " ,1 ,% a0
move. l % a0 ,% a4
rts
fp_put_a5 :
printf P R E G I S T E R ," { a5 < - % 0 8 x } " ,1 ,% a0
move. l % a0 ,% a5
rts
fp_put_a6 :
printf P R E G I S T E R ," { a6 < - % 0 8 x } " ,1 ,% a0
move. l % a0 ,% a6
rts
fp_put_a7 :
printf P R E G I S T E R ," { a7 < - % 0 8 x } " ,1 ,% a0
move. l % a0 ,% u s p
rts
.data
.align 4
fp_debugprint :
| .long PMDECODE
.long PMINSTR+ P M D E C O D E + P M C O N V + P M N O R M
| .long PMCONV+ P M N O R M + P M I N S T R
| .long 0