|
|
1.1 ! root 1: /* ! 2: NetWinder Floating Point Emulator ! 3: (c) Rebel.com, 1998-1999 ! 4: ! 5: Direct questions, comments to Scott Bambrough <[email protected]> ! 6: ! 7: This program is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 2 of the License, or ! 10: (at your option) any later version. ! 11: ! 12: This program is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with this program; if not, write to the Free Software ! 19: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 20: */ ! 21: ! 22: #ifndef __FPA11_H__ ! 23: #define __FPA11_H__ ! 24: ! 25: #include <stdlib.h> ! 26: #include <stdio.h> ! 27: #include <errno.h> ! 28: ! 29: #define GET_FPA11() (qemufpa) ! 30: ! 31: /* ! 32: * The processes registers are always at the very top of the 8K ! 33: * stack+task struct. Use the same method as 'current' uses to ! 34: * reach them. ! 35: */ ! 36: extern unsigned int *user_registers; ! 37: ! 38: #define GET_USERREG() (user_registers) ! 39: ! 40: /* Need task_struct */ ! 41: //#include <linux/sched.h> ! 42: ! 43: /* includes */ ! 44: #include "fpsr.h" /* FP control and status register definitions */ ! 45: #include "softfloat.h" ! 46: ! 47: #define typeNone 0x00 ! 48: #define typeSingle 0x01 ! 49: #define typeDouble 0x02 ! 50: #define typeExtended 0x03 ! 51: ! 52: /* ! 53: * This must be no more and no less than 12 bytes. ! 54: */ ! 55: typedef union tagFPREG { ! 56: floatx80 fExtended; ! 57: float64 fDouble; ! 58: float32 fSingle; ! 59: } FPREG; ! 60: ! 61: /* ! 62: * FPA11 device model. ! 63: * ! 64: * This structure is exported to user space. Do not re-order. ! 65: * Only add new stuff to the end, and do not change the size of ! 66: * any element. Elements of this structure are used by user ! 67: * space, and must match struct user_fp in include/asm-arm/user.h. ! 68: * We include the byte offsets below for documentation purposes. ! 69: * ! 70: * The size of this structure and FPREG are checked by fpmodule.c ! 71: * on initialisation. If the rules have been broken, NWFPE will ! 72: * not initialise. ! 73: */ ! 74: typedef struct tagFPA11 { ! 75: /* 0 */ FPREG fpreg[8]; /* 8 floating point registers */ ! 76: /* 96 */ FPSR fpsr; /* floating point status register */ ! 77: /* 100 */ FPCR fpcr; /* floating point control register */ ! 78: /* 104 */ unsigned char fType[8]; /* type of floating point value held in ! 79: floating point registers. One of none ! 80: single, double or extended. */ ! 81: /* 112 */ int initflag; /* this is special. The kernel guarantees ! 82: to set it to 0 when a thread is launched, ! 83: so we can use it to detect whether this ! 84: instance of the emulator needs to be ! 85: initialised. */ ! 86: float_status fp_status; /* QEMU float emulator status */ ! 87: } FPA11; ! 88: ! 89: extern FPA11* qemufpa; ! 90: ! 91: extern void resetFPA11(void); ! 92: extern void SetRoundingMode(const unsigned int); ! 93: extern void SetRoundingPrecision(const unsigned int); ! 94: ! 95: static inline unsigned int readRegister(unsigned int reg) ! 96: { ! 97: return (user_registers[(reg)]); ! 98: } ! 99: ! 100: static inline void writeRegister(unsigned int x, unsigned int y) ! 101: { ! 102: #if 0 ! 103: printf("writing %d to r%d\n",y,x); ! 104: #endif ! 105: user_registers[(x)]=(y); ! 106: } ! 107: ! 108: static inline void writeConditionCodes(unsigned int x) ! 109: { ! 110: #if 0 ! 111: unsigned int y; ! 112: unsigned int ZF; ! 113: printf("setting flags to %x from %x\n",x,user_registers[16]); ! 114: #endif ! 115: user_registers[16]=(x); // cpsr ! 116: user_registers[17]=(x>>29)&1; // cf ! 117: user_registers[18]=(x<<3)&(1<<31); // vf ! 118: user_registers[19]=x&(1<<31); // nzf ! 119: if(!(x&(1<<30))) user_registers[19]++; // nzf must be non-zero for zf to be cleared ! 120: ! 121: #if 0 ! 122: ZF = (user_registers[19] == 0); ! 123: y=user_registers[16] | (user_registers[19] & 0x80000000) | (ZF << 30) | ! 124: (user_registers[17] << 29) | ((user_registers[18] & 0x80000000) >> 3); ! 125: if(y != x) ! 126: printf("GODDAM SHIIIIIIIIIIIIIIIIT! %x %x nzf %x zf %x\n",x,y,user_registers[19],ZF); ! 127: #endif ! 128: } ! 129: ! 130: #define REG_PC 15 ! 131: ! 132: unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, unsigned int* qregs); ! 133: ! 134: /* included only for get_user/put_user macros */ ! 135: #include "qemu.h" ! 136: ! 137: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.