2005-04-17 02:20:36 +04:00
/ *
NetWinder F l o a t i n g P o i n t E m u l a t o r
( c) R e b e l . C O M , 1 9 9 8
( c) 1 9 9 8 , 1 9 9 9 P h i l i p B l u n d e l l
Direct q u e s t i o n s , c o m m e n t s t o S c o t t B a m b r o u g h < s c o t t b @netwinder.org>
This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or modify
it u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e a s p u b l i s h e d b y
the F r e e S o f t w a r e F o u n d a t i o n ; either version 2 of the License, or
( at y o u r o p t i o n ) a n y l a t e r v e r s i o n .
This p r o g r a m i s d i s t r i b u t e d i n t h e h o p e t h a t i t w i l l b e u s e f u l ,
but W I T H O U T A N Y W A R R A N T Y ; without even the implied warranty of
MERCHANTABILITY o r 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 . S e e t h e
GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e d e t a i l s .
You s h o u l d h a v e r e c e i v e d a c o p y o f t h e G N U G e n e r a l P u b l i c L i c e n s e
along w i t h t h i s p r o g r a m ; if not, write to the Free Software
Foundation, I n c . , 6 7 5 M a s s A v e , C a m b r i d g e , M A 0 2 1 3 9 , U S A .
* /
2014-06-30 19:29:12 +04:00
# include < a s m / a s s e m b l e r . h >
2011-12-12 22:44:49 +04:00
# include < a s m / o p c o d e s . h >
2005-04-17 02:20:36 +04:00
/ * This i s t h e k e r n e l ' s e n t r y p o i n t i n t o t h e f l o a t i n g p o i n t e m u l a t o r .
It i s c a l l e d f r o m t h e k e r n e l w i t h c o d e s i m i l a r t o t h i s :
sub r4 , r5 , #4
ldrt r0 , [ r4 ] @ r0 = instruction
adrsvc a l , r9 , r e t _ f r o m _ e x c e p t i o n @ r9 = normal FP return
adrsvc a l , l r , f p u n d e f i n s t r @ lr = undefined instr return
get_ c u r r e n t _ t a s k r10
mov r8 , #1
strb r8 , [ r10 , #T S K _ U S E D _ M A T H ] @ s e t c u r r e n t - > u s e d _ m a t h
add r10 , r10 , #T S S _ F P E S A V E @ r 10 = w o r k s p a c e
ldr r4 , . L C 2
ldr p c , [ r4 ] @ Call FP emulator entry point
The k e r n e l e x p e c t s t h e e m u l a t o r t o r e t u r n v i a o n e o f t w o p o s s i b l e
points o f r e t u r n i t p a s s e s t o t h e e m u l a t o r . T h e e m u l a t o r , i f
successful i n i t s e m u l a t i o n , j u m p s t o r e t _ f r o m _ e x c e p t i o n ( p a s s e d i n
r9 ) a n d t h e k e r n e l t a k e s c a r e o f r e t u r n i n g c o n t r o l f r o m t h e t r a p t o
the u s e r c o d e . I f t h e e m u l a t o r i s u n a b l e t o e m u l a t e t h e i n s t r u c t i o n ,
it r e t u r n s v i a _ f p u n d e f i n s t r ( p a s s e d v i a l r ) a n d t h e k e r n e l h a l t s t h e
user p r o g r a m w i t h a c o r e d u m p .
On e n t r y t o t h e e m u l a t o r r10 p o i n t s t o a n a r e a o f p r i v a t e F P w o r k s p a c e
reserved i n t h e t h r e a d s t r u c t u r e f o r t h i s p r o c e s s . T h i s i s w h e r e t h e
emulator s a v e s i t s r e g i s t e r s a c r o s s c a l l s . T h e f i r s t w o r d o f t h i s a r e a
is u s e d a s a f l a g t o d e t e c t t h e f i r s t t i m e a p r o c e s s u s e s f l o a t i n g p o i n t ,
so t h a t t h e e m u l a t o r s t a r t u p c o s t c a n b e a v o i d e d f o r t a s k s t h a t d o n ' t
want i t .
This r o u t i n e d o e s t h r e e t h i n g s :
1 ) The k e r n e l h a s c r e a t e d a s t r u c t p t _ r e g s o n t h e s t a c k a n d s a v e d t h e
user r e g i s t e r s i n t o i t . S e e / u s r / i n c l u d e / a s m / p r o c / p t r a c e . h f o r d e t a i l s .
2 ) It c a l l s E m u l a t e A l l t o e m u l a t e a f l o a t i n g p o i n t i n s t r u c t i o n .
EmulateAll r e t u r n s 1 i f t h e e m u l a t i o n w a s s u c c e s s f u l , o r 0 i f n o t .
3 ) If a n i n s t r u c t i o n h a s b e e n e m u l a t e d s u c c e s s f u l l y , i t l o o k s a h e a d a t
the n e x t i n s t r u c t i o n . I f i t i s a f l o a t i n g p o i n t i n s t r u c t i o n , i t
executes t h e i n s t r u c t i o n , w i t h o u t r e t u r n i n g t o u s e r s p a c e . I n t h i s
way i t r e p e a t e d l y l o o k s a h e a d a n d e x e c u t e s f l o a t i n g p o i n t i n s t r u c t i o n s
until i t e n c o u n t e r s a n o n f l o a t i n g p o i n t i n s t r u c t i o n , a t w h i c h t i m e i t
returns v i a _ f p r e t u r n .
This i s d o n e t o r e d u c e t h e e f f e c t o f t h e t r a p o v e r h e a d o n e a c h
floating p o i n t i n s t r u c t i o n s . G C C a t t e m p t s t o g r o u p f l o a t i n g p o i n t
instructions t o a l l o w t h e e m u l a t o r t o s p r e a d t h e c o s t o f t h e t r a p o v e r
several f l o a t i n g p o i n t i n s t r u c t i o n s . * /
2007-09-25 18:21:00 +04:00
# include < a s m / a s m - o f f s e t s . h >
2005-04-17 02:20:36 +04:00
.globl nwfpe_enter
nwfpe_enter :
mov r4 , l r @ save the failure-return addresses
mov s l , s p @ we access the registers via 'sl'
2007-09-25 18:21:00 +04:00
ldr r5 , [ s p , #S _ P C ] @ g e t c o n t e n t s o f P C ;
mov r6 , r0 @ save the opcode
2005-04-17 02:20:36 +04:00
emulate :
2007-09-25 18:21:00 +04:00
ldr r1 , [ s p , #S _ P S R ] @ f e t c h t h e P S R
2011-12-12 22:44:49 +04:00
bl a r m _ c h e c k _ c o n d i t i o n @ check the condition
cmp r0 , #A R M _ O P C O D E _ C O N D T E S T _ P A S S @ c o n d i t i o n p a s s e d ?
2007-09-25 18:21:00 +04:00
@ if condition code failed to match, next insn
2011-12-12 22:44:49 +04:00
bne n e x t @ get the next instruction;
2007-09-25 18:21:00 +04:00
mov r0 , r6 @ prepare for EmulateAll()
2005-04-17 02:20:36 +04:00
bl E m u l a t e A l l @ emulate the instruction
cmp r0 , #0 @ was emulation successful
2014-06-30 19:29:12 +04:00
reteq r4 @ no, return failure
2005-04-17 02:20:36 +04:00
next :
2015-09-07 02:29:15 +03:00
uaccess_ e n a b l e r3
2005-04-17 02:20:36 +04:00
.Lx1 : ldrt r6 , [ r5 ] , #4 @ get the next instruction and
@ increment PC
2015-09-07 02:29:15 +03:00
uaccess_ d i s a b l e r3
2005-04-17 02:20:36 +04:00
and r2 , r6 , #0x0F000000 @ test for FP insns
teq r2 , #0x0C000000
teqne r2 , #0x0D000000
teqne r2 , #0x0E000000
2014-06-30 19:29:12 +04:00
retne r9 @ return ok if not a fp insn
2005-04-17 02:20:36 +04:00
2007-09-25 18:21:00 +04:00
str r5 , [ s p , #S _ P C ] @ u p d a t e P C c o p y i n r e g s
2005-04-17 02:20:36 +04:00
mov r0 , r6 @ save a copy
2007-09-25 18:21:00 +04:00
b e m u l a t e @ check condition and emulate
2005-04-17 02:20:36 +04:00
@ We need to be prepared for the instructions at .Lx1 and .Lx2
@ to fault. Emit the appropriate exception gunk to fix things up.
@ ??? For some reason, faults can happen at .Lx2 even with a
@ plain LDR instruction. Weird, but it seems harmless.
2015-03-24 12:41:09 +03:00
.pushsection .text .fixup , " ax"
2005-04-17 02:20:36 +04:00
.align 2
2014-06-30 19:29:12 +04:00
.Lfix : ret r9 @ let the user eat segfaults
2010-04-19 13:15:03 +04:00
.popsection
2005-04-17 02:20:36 +04:00
2010-04-19 13:15:03 +04:00
.pushsection _ _ ex_ t a b l e ," a "
2005-04-17 02:20:36 +04:00
.align 3
.long .Lx1 , .Lfix
2010-04-19 13:15:03 +04:00
.popsection