Statistics
| Branch: | Revision:

root / target-arm / nwfpe / fpa11.h @ d3c61721

History | View | Annotate | Download (4 kB)

1 00406dff bellard
/*
2 00406dff bellard
    NetWinder Floating Point Emulator
3 00406dff bellard
    (c) Rebel.com, 1998-1999
4 00406dff bellard
    
5 00406dff bellard
    Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
6 00406dff bellard

7 00406dff bellard
    This program is free software; you can redistribute it and/or modify
8 00406dff bellard
    it under the terms of the GNU General Public License as published by
9 00406dff bellard
    the Free Software Foundation; either version 2 of the License, or
10 00406dff bellard
    (at your option) any later version.
11 00406dff bellard

12 00406dff bellard
    This program is distributed in the hope that it will be useful,
13 00406dff bellard
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 00406dff bellard
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 00406dff bellard
    GNU General Public License for more details.
16 00406dff bellard

17 00406dff bellard
    You should have received a copy of the GNU General Public License
18 00406dff bellard
    along with this program; if not, write to the Free Software
19 00406dff bellard
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 00406dff bellard
*/
21 00406dff bellard
22 00406dff bellard
#ifndef __FPA11_H__
23 00406dff bellard
#define __FPA11_H__
24 00406dff bellard
25 00406dff bellard
#define GET_FPA11() (qemufpa)
26 00406dff bellard
27 00406dff bellard
/*
28 00406dff bellard
 * The processes registers are always at the very top of the 8K
29 00406dff bellard
 * stack+task struct.  Use the same method as 'current' uses to
30 00406dff bellard
 * reach them.
31 00406dff bellard
 */
32 00406dff bellard
extern unsigned int *user_registers;
33 00406dff bellard
34 00406dff bellard
#define GET_USERREG() (user_registers)
35 00406dff bellard
36 00406dff bellard
/* Need task_struct */
37 00406dff bellard
//#include <linux/sched.h>
38 00406dff bellard
39 00406dff bellard
/* includes */
40 00406dff bellard
#include "fpsr.h"                /* FP control and status register definitions */
41 00406dff bellard
#include "softfloat.h"
42 00406dff bellard
43 00406dff bellard
#define                typeNone                0x00
44 00406dff bellard
#define                typeSingle                0x01
45 00406dff bellard
#define                typeDouble                0x02
46 00406dff bellard
#define                typeExtended                0x03
47 00406dff bellard
48 00406dff bellard
/*
49 00406dff bellard
 * This must be no more and no less than 12 bytes.
50 00406dff bellard
 */
51 00406dff bellard
typedef union tagFPREG {
52 00406dff bellard
   floatx80 fExtended;
53 00406dff bellard
   float64  fDouble;
54 00406dff bellard
   float32  fSingle;
55 00406dff bellard
} FPREG;
56 00406dff bellard
57 00406dff bellard
/*
58 00406dff bellard
 * FPA11 device model.
59 00406dff bellard
 *
60 00406dff bellard
 * This structure is exported to user space.  Do not re-order.
61 00406dff bellard
 * Only add new stuff to the end, and do not change the size of
62 00406dff bellard
 * any element.  Elements of this structure are used by user
63 00406dff bellard
 * space, and must match struct user_fp in include/asm-arm/user.h.
64 00406dff bellard
 * We include the byte offsets below for documentation purposes.
65 00406dff bellard
 *
66 00406dff bellard
 * The size of this structure and FPREG are checked by fpmodule.c
67 00406dff bellard
 * on initialisation.  If the rules have been broken, NWFPE will
68 00406dff bellard
 * not initialise.
69 00406dff bellard
 */
70 00406dff bellard
typedef struct tagFPA11 {
71 00406dff bellard
/*   0 */  FPREG fpreg[8];                /* 8 floating point registers */
72 00406dff bellard
/*  96 */  FPSR fpsr;                        /* floating point status register */
73 00406dff bellard
/* 100 */  FPCR fpcr;                        /* floating point control register */
74 00406dff bellard
/* 104 */  unsigned char fType[8];        /* type of floating point value held in
75 00406dff bellard
                                           floating point registers.  One of none
76 00406dff bellard
                                           single, double or extended. */
77 00406dff bellard
/* 112 */  int initflag;                /* this is special.  The kernel guarantees
78 00406dff bellard
                                           to set it to 0 when a thread is launched,
79 00406dff bellard
                                           so we can use it to detect whether this
80 00406dff bellard
                                           instance of the emulator needs to be
81 00406dff bellard
                                           initialised. */
82 00406dff bellard
} FPA11;
83 00406dff bellard
84 00406dff bellard
extern FPA11* qemufpa;
85 00406dff bellard
86 00406dff bellard
extern void resetFPA11(void);
87 00406dff bellard
extern void SetRoundingMode(const unsigned int);
88 00406dff bellard
extern void SetRoundingPrecision(const unsigned int);
89 00406dff bellard
90 00406dff bellard
#define get_user(x,y) ((x)=*(y))
91 00406dff bellard
#define put_user(x,y) (*(y)=(x))
92 00406dff bellard
static inline unsigned int readRegister(unsigned int reg)
93 00406dff bellard
{
94 00406dff bellard
    return (user_registers[(reg)]);
95 00406dff bellard
}
96 00406dff bellard
97 00406dff bellard
static inline void writeRegister(unsigned int x, unsigned int y)
98 00406dff bellard
{
99 00406dff bellard
#if 0
100 00406dff bellard
        printf("writing %d to r%d\n",y,x);
101 00406dff bellard
#endif
102 00406dff bellard
        user_registers[(x)]=(y);
103 00406dff bellard
}
104 00406dff bellard
105 00406dff bellard
static inline void writeConditionCodes(unsigned int x)
106 00406dff bellard
{
107 00406dff bellard
#if 0
108 00406dff bellard
unsigned        int y;
109 00406dff bellard
unsigned    int ZF;
110 00406dff bellard
        printf("setting flags to %x from %x\n",x,user_registers[16]);
111 00406dff bellard
#endif
112 00406dff bellard
        user_registers[16]=(x);        // cpsr
113 00406dff bellard
        user_registers[17]=(x>>29)&1;        // cf
114 00406dff bellard
        user_registers[18]=(x<<3)&(1<<31);        // vf
115 00406dff bellard
        user_registers[19]=x&(1<<31);        // nzf
116 00406dff bellard
        if(!(x&(1<<30))) user_registers[19]++;        // nzf must be non-zero for zf to be cleared
117 00406dff bellard
118 00406dff bellard
#if 0
119 00406dff bellard
        ZF = (user_registers[19] == 0);
120 00406dff bellard
        y=user_registers[16] | (user_registers[19] & 0x80000000) | (ZF << 30) | 
121 00406dff bellard
                    (user_registers[17] << 29) | ((user_registers[18] & 0x80000000) >> 3);
122 00406dff bellard
        if(y != x)
123 00406dff bellard
                printf("GODDAM SHIIIIIIIIIIIIIIIIT! %x %x nzf %x zf %x\n",x,y,user_registers[19],ZF);
124 00406dff bellard
#endif                    
125 00406dff bellard
}
126 00406dff bellard
127 00406dff bellard
#define REG_PC 15
128 00406dff bellard
129 00406dff bellard
unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, unsigned int* qregs);
130 00406dff bellard
131 00406dff bellard
#endif