Statistics
| Branch: | Revision:

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

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