xref: /OK3568_Linux_fs/kernel/arch/arm/nwfpe/fpa11.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun     NetWinder Floating Point Emulator
4*4882a593Smuzhiyun     (c) Rebel.com, 1998-1999
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #ifndef __FPA11_H__
11*4882a593Smuzhiyun #define __FPA11_H__
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #define GET_FPA11() ((FPA11 *)(&current_thread_info()->fpstate))
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun /*
16*4882a593Smuzhiyun  * The processes registers are always at the very top of the 8K
17*4882a593Smuzhiyun  * stack+task struct.  Use the same method as 'current' uses to
18*4882a593Smuzhiyun  * reach them.
19*4882a593Smuzhiyun  */
20*4882a593Smuzhiyun #define GET_USERREG() ((struct pt_regs *)(THREAD_START_SP + (unsigned long)current_thread_info()) - 1)
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #include <linux/thread_info.h>
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun /* includes */
25*4882a593Smuzhiyun #include "fpsr.h"		/* FP control and status register definitions */
26*4882a593Smuzhiyun #include "milieu.h"
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun struct roundingData {
29*4882a593Smuzhiyun     int8 mode;
30*4882a593Smuzhiyun     int8 precision;
31*4882a593Smuzhiyun     signed char exception;
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #include "softfloat.h"
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #define		typeNone		0x00
37*4882a593Smuzhiyun #define		typeSingle		0x01
38*4882a593Smuzhiyun #define		typeDouble		0x02
39*4882a593Smuzhiyun #define		typeExtended		0x03
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /*
42*4882a593Smuzhiyun  * This must be no more and no less than 12 bytes.
43*4882a593Smuzhiyun  */
44*4882a593Smuzhiyun typedef union tagFPREG {
45*4882a593Smuzhiyun 	float32 fSingle;
46*4882a593Smuzhiyun 	float64 fDouble;
47*4882a593Smuzhiyun #ifdef CONFIG_FPE_NWFPE_XP
48*4882a593Smuzhiyun 	floatx80 fExtended;
49*4882a593Smuzhiyun #else
50*4882a593Smuzhiyun 	u32 padding[3];
51*4882a593Smuzhiyun #endif
52*4882a593Smuzhiyun } __attribute__ ((packed,aligned(4))) FPREG;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun /*
55*4882a593Smuzhiyun  * FPA11 device model.
56*4882a593Smuzhiyun  *
57*4882a593Smuzhiyun  * This structure is exported to user space.  Do not re-order.
58*4882a593Smuzhiyun  * Only add new stuff to the end, and do not change the size of
59*4882a593Smuzhiyun  * any element.  Elements of this structure are used by user
60*4882a593Smuzhiyun  * space, and must match struct user_fp in <asm/user.h>.
61*4882a593Smuzhiyun  * We include the byte offsets below for documentation purposes.
62*4882a593Smuzhiyun  *
63*4882a593Smuzhiyun  * The size of this structure and FPREG are checked by fpmodule.c
64*4882a593Smuzhiyun  * on initialisation.  If the rules have been broken, NWFPE will
65*4882a593Smuzhiyun  * not initialise.
66*4882a593Smuzhiyun  */
67*4882a593Smuzhiyun typedef struct tagFPA11 {
68*4882a593Smuzhiyun /*   0 */ FPREG fpreg[8];	/* 8 floating point registers */
69*4882a593Smuzhiyun /*  96 */ FPSR fpsr;		/* floating point status register */
70*4882a593Smuzhiyun /* 100 */ FPCR fpcr;		/* floating point control register */
71*4882a593Smuzhiyun /* 104 */ unsigned char fType[8];	/* type of floating point value held in
72*4882a593Smuzhiyun 					   floating point registers.  One of
73*4882a593Smuzhiyun 					   none, single, double or extended. */
74*4882a593Smuzhiyun /* 112 */ int initflag;		/* this is special.  The kernel guarantees
75*4882a593Smuzhiyun 				   to set it to 0 when a thread is launched,
76*4882a593Smuzhiyun 				   so we can use it to detect whether this
77*4882a593Smuzhiyun 				   instance of the emulator needs to be
78*4882a593Smuzhiyun 				   initialised. */
79*4882a593Smuzhiyun } __attribute__ ((packed,aligned(4))) FPA11;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun extern int8 SetRoundingMode(const unsigned int);
82*4882a593Smuzhiyun extern int8 SetRoundingPrecision(const unsigned int);
83*4882a593Smuzhiyun extern void nwfpe_init_fpa(union fp_state *fp);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun extern unsigned int EmulateAll(unsigned int opcode);
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun extern unsigned int EmulateCPDT(const unsigned int opcode);
88*4882a593Smuzhiyun extern unsigned int EmulateCPDO(const unsigned int opcode);
89*4882a593Smuzhiyun extern unsigned int EmulateCPRT(const unsigned int opcode);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /* fpa11_cpdt.c */
92*4882a593Smuzhiyun extern unsigned int PerformLDF(const unsigned int opcode);
93*4882a593Smuzhiyun extern unsigned int PerformSTF(const unsigned int opcode);
94*4882a593Smuzhiyun extern unsigned int PerformLFM(const unsigned int opcode);
95*4882a593Smuzhiyun extern unsigned int PerformSFM(const unsigned int opcode);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /* single_cpdo.c */
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun extern unsigned int SingleCPDO(struct roundingData *roundData,
100*4882a593Smuzhiyun 			       const unsigned int opcode, FPREG * rFd);
101*4882a593Smuzhiyun /* double_cpdo.c */
102*4882a593Smuzhiyun extern unsigned int DoubleCPDO(struct roundingData *roundData,
103*4882a593Smuzhiyun 			       const unsigned int opcode, FPREG * rFd);
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun /* extneded_cpdo.c */
106*4882a593Smuzhiyun extern unsigned int ExtendedCPDO(struct roundingData *roundData,
107*4882a593Smuzhiyun 				 const unsigned int opcode, FPREG * rFd);
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun #endif
110