2005-04-17 02:20:36 +04:00
/*
NetWinder Floating Point Emulator
( c ) Rebel . com , 1998 - 1999
Direct questions , comments to Scott Bambrough < scottb @ netwinder . org >
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# ifndef __FPA11_H__
# define __FPA11_H__
# define GET_FPA11() ((FPA11 *)(¤t_thread_info()->fpstate))
/*
* The processes registers are always at the very top of the 8 K
* stack + task struct . Use the same method as ' current ' uses to
* reach them .
*/
2005-07-17 13:54:50 +04:00
# define GET_USERREG() ((struct pt_regs *)(THREAD_START_SP + (unsigned long)current_thread_info()) - 1)
2005-04-17 02:20:36 +04:00
# include <linux/thread_info.h>
/* includes */
# include "fpsr.h" /* FP control and status register definitions */
# include "milieu.h"
2005-08-03 22:49:17 +04:00
struct roundingData {
int8 mode ;
int8 precision ;
signed char exception ;
} ;
2005-04-17 02:20:36 +04:00
# include "softfloat.h"
# define typeNone 0x00
# define typeSingle 0x01
# define typeDouble 0x02
# define typeExtended 0x03
/*
* This must be no more and no less than 12 bytes .
*/
typedef union tagFPREG {
float32 fSingle ;
float64 fDouble ;
# ifdef CONFIG_FPE_NWFPE_XP
floatx80 fExtended ;
# else
2005-11-08 00:12:08 +03:00
u32 padding [ 3 ] ;
2005-04-17 02:20:36 +04:00
# endif
2006-01-14 19:36:50 +03:00
} __attribute__ ( ( packed , aligned ( 4 ) ) ) FPREG ;
2005-04-17 02:20:36 +04:00
/*
* FPA11 device model .
*
* This structure is exported to user space . Do not re - order .
* Only add new stuff to the end , and do not change the size of
* any element . Elements of this structure are used by user
2008-08-02 13:55:55 +04:00
* space , and must match struct user_fp in < asm / user . h > .
2005-04-17 02:20:36 +04:00
* We include the byte offsets below for documentation purposes .
*
* The size of this structure and FPREG are checked by fpmodule . c
* on initialisation . If the rules have been broken , NWFPE will
* not initialise .
*/
typedef struct tagFPA11 {
/* 0 */ FPREG fpreg [ 8 ] ; /* 8 floating point registers */
/* 96 */ FPSR fpsr ; /* floating point status register */
/* 100 */ FPCR fpcr ; /* floating point control register */
/* 104 */ unsigned char fType [ 8 ] ; /* type of floating point value held in
floating point registers . One of
none , single , double or extended . */
/* 112 */ int initflag ; /* this is special. The kernel guarantees
to set it to 0 when a thread is launched ,
so we can use it to detect whether this
instance of the emulator needs to be
initialised . */
2006-01-14 19:36:50 +03:00
} __attribute__ ( ( packed , aligned ( 4 ) ) ) FPA11 ;
2005-04-17 02:20:36 +04:00
2005-08-03 22:49:17 +04:00
extern int8 SetRoundingMode ( const unsigned int ) ;
extern int8 SetRoundingPrecision ( const unsigned int ) ;
2005-04-17 02:20:36 +04:00
extern void nwfpe_init_fpa ( union fp_state * fp ) ;
2005-10-12 22:58:10 +04:00
extern unsigned int EmulateAll ( unsigned int opcode ) ;
extern unsigned int EmulateCPDT ( const unsigned int opcode ) ;
extern unsigned int EmulateCPDO ( const unsigned int opcode ) ;
extern unsigned int EmulateCPRT ( const unsigned int opcode ) ;
/* fpa11_cpdt.c */
extern unsigned int PerformLDF ( const unsigned int opcode ) ;
extern unsigned int PerformSTF ( const unsigned int opcode ) ;
extern unsigned int PerformLFM ( const unsigned int opcode ) ;
extern unsigned int PerformSFM ( const unsigned int opcode ) ;
/* single_cpdo.c */
extern unsigned int SingleCPDO ( struct roundingData * roundData ,
const unsigned int opcode , FPREG * rFd ) ;
/* double_cpdo.c */
extern unsigned int DoubleCPDO ( struct roundingData * roundData ,
const unsigned int opcode , FPREG * rFd ) ;
2009-04-17 15:29:22 +04:00
/* extneded_cpdo.c */
extern unsigned int ExtendedCPDO ( struct roundingData * roundData ,
const unsigned int opcode , FPREG * rFd ) ;
2005-04-17 02:20:36 +04:00
# endif