1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun NetWinder Floating Point Emulator 3*4882a593Smuzhiyun (c) Rebel.COM, 1998,1999 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun Direct questions, comments to Scott Bambrough <scottb@netwinder.org> 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun This program is free software; you can redistribute it and/or modify 8*4882a593Smuzhiyun it under the terms of the GNU General Public License as published by 9*4882a593Smuzhiyun the Free Software Foundation; either version 2 of the License, or 10*4882a593Smuzhiyun (at your option) any later version. 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun This program is distributed in the hope that it will be useful, 13*4882a593Smuzhiyun but WITHOUT ANY WARRANTY; without even the implied warranty of 14*4882a593Smuzhiyun MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*4882a593Smuzhiyun GNU General Public License for more details. 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun You should have received a copy of the GNU General Public License 18*4882a593Smuzhiyun along with this program; if not, write to the Free Software 19*4882a593Smuzhiyun Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20*4882a593Smuzhiyun*/ 21*4882a593Smuzhiyun 22*4882a593Smuzhiyunstatic inline unsigned long readRegister(const unsigned int nReg) 23*4882a593Smuzhiyun{ 24*4882a593Smuzhiyun /* Note: The CPU thinks it has dealt with the current instruction. 25*4882a593Smuzhiyun As a result the program counter has been advanced to the next 26*4882a593Smuzhiyun instruction, and points 4 bytes beyond the actual instruction 27*4882a593Smuzhiyun that caused the invalid instruction trap to occur. We adjust 28*4882a593Smuzhiyun for this in this routine. LDF/STF instructions with Rn = PC 29*4882a593Smuzhiyun depend on the PC being correct, as they use PC+8 in their 30*4882a593Smuzhiyun address calculations. */ 31*4882a593Smuzhiyun struct pt_regs *regs = GET_USERREG(); 32*4882a593Smuzhiyun unsigned int val = regs->uregs[nReg]; 33*4882a593Smuzhiyun if (REG_PC == nReg) 34*4882a593Smuzhiyun val -= 4; 35*4882a593Smuzhiyun return val; 36*4882a593Smuzhiyun} 37*4882a593Smuzhiyun 38*4882a593Smuzhiyunstatic inline void 39*4882a593SmuzhiyunwriteRegister(const unsigned int nReg, const unsigned long val) 40*4882a593Smuzhiyun{ 41*4882a593Smuzhiyun struct pt_regs *regs = GET_USERREG(); 42*4882a593Smuzhiyun regs->uregs[nReg] = val; 43*4882a593Smuzhiyun} 44*4882a593Smuzhiyun 45*4882a593Smuzhiyunstatic inline unsigned long readCPSR(void) 46*4882a593Smuzhiyun{ 47*4882a593Smuzhiyun return (readRegister(REG_CPSR)); 48*4882a593Smuzhiyun} 49*4882a593Smuzhiyun 50*4882a593Smuzhiyunstatic inline void writeCPSR(const unsigned long val) 51*4882a593Smuzhiyun{ 52*4882a593Smuzhiyun writeRegister(REG_CPSR, val); 53*4882a593Smuzhiyun} 54*4882a593Smuzhiyun 55*4882a593Smuzhiyunstatic inline unsigned long readConditionCodes(void) 56*4882a593Smuzhiyun{ 57*4882a593Smuzhiyun#ifdef __FPEM_TEST__ 58*4882a593Smuzhiyun return (0); 59*4882a593Smuzhiyun#else 60*4882a593Smuzhiyun return (readCPSR() & CC_MASK); 61*4882a593Smuzhiyun#endif 62*4882a593Smuzhiyun} 63*4882a593Smuzhiyun 64*4882a593Smuzhiyunstatic inline void writeConditionCodes(const unsigned long val) 65*4882a593Smuzhiyun{ 66*4882a593Smuzhiyun struct pt_regs *regs = GET_USERREG(); 67*4882a593Smuzhiyun unsigned long rval; 68*4882a593Smuzhiyun /* 69*4882a593Smuzhiyun * Operate directly on userRegisters since 70*4882a593Smuzhiyun * the CPSR may be the PC register itself. 71*4882a593Smuzhiyun */ 72*4882a593Smuzhiyun rval = regs->ARM_cpsr & ~CC_MASK; 73*4882a593Smuzhiyun regs->ARM_cpsr = rval | (val & CC_MASK); 74*4882a593Smuzhiyun} 75