18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci NetWinder Floating Point Emulator 38c2ecf20Sopenharmony_ci (c) Rebel.COM, 1998,1999 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci Direct questions, comments to Scott Bambrough <scottb@netwinder.org> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci This program is free software; you can redistribute it and/or modify 88c2ecf20Sopenharmony_ci it under the terms of the GNU General Public License as published by 98c2ecf20Sopenharmony_ci the Free Software Foundation; either version 2 of the License, or 108c2ecf20Sopenharmony_ci (at your option) any later version. 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci This program is distributed in the hope that it will be useful, 138c2ecf20Sopenharmony_ci but WITHOUT ANY WARRANTY; without even the implied warranty of 148c2ecf20Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 158c2ecf20Sopenharmony_ci GNU General Public License for more details. 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci You should have received a copy of the GNU General Public License 188c2ecf20Sopenharmony_ci along with this program; if not, write to the Free Software 198c2ecf20Sopenharmony_ci Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 208c2ecf20Sopenharmony_ci*/ 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic inline unsigned long readRegister(const unsigned int nReg) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci /* Note: The CPU thinks it has dealt with the current instruction. 258c2ecf20Sopenharmony_ci As a result the program counter has been advanced to the next 268c2ecf20Sopenharmony_ci instruction, and points 4 bytes beyond the actual instruction 278c2ecf20Sopenharmony_ci that caused the invalid instruction trap to occur. We adjust 288c2ecf20Sopenharmony_ci for this in this routine. LDF/STF instructions with Rn = PC 298c2ecf20Sopenharmony_ci depend on the PC being correct, as they use PC+8 in their 308c2ecf20Sopenharmony_ci address calculations. */ 318c2ecf20Sopenharmony_ci struct pt_regs *regs = GET_USERREG(); 328c2ecf20Sopenharmony_ci unsigned int val = regs->uregs[nReg]; 338c2ecf20Sopenharmony_ci if (REG_PC == nReg) 348c2ecf20Sopenharmony_ci val -= 4; 358c2ecf20Sopenharmony_ci return val; 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic inline void 398c2ecf20Sopenharmony_ciwriteRegister(const unsigned int nReg, const unsigned long val) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci struct pt_regs *regs = GET_USERREG(); 428c2ecf20Sopenharmony_ci regs->uregs[nReg] = val; 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic inline unsigned long readCPSR(void) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci return (readRegister(REG_CPSR)); 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic inline void writeCPSR(const unsigned long val) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci writeRegister(REG_CPSR, val); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic inline unsigned long readConditionCodes(void) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci#ifdef __FPEM_TEST__ 588c2ecf20Sopenharmony_ci return (0); 598c2ecf20Sopenharmony_ci#else 608c2ecf20Sopenharmony_ci return (readCPSR() & CC_MASK); 618c2ecf20Sopenharmony_ci#endif 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic inline void writeConditionCodes(const unsigned long val) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci struct pt_regs *regs = GET_USERREG(); 678c2ecf20Sopenharmony_ci unsigned long rval; 688c2ecf20Sopenharmony_ci /* 698c2ecf20Sopenharmony_ci * Operate directly on userRegisters since 708c2ecf20Sopenharmony_ci * the CPSR may be the PC register itself. 718c2ecf20Sopenharmony_ci */ 728c2ecf20Sopenharmony_ci rval = regs->ARM_cpsr & ~CC_MASK; 738c2ecf20Sopenharmony_ci regs->ARM_cpsr = rval | (val & CC_MASK); 748c2ecf20Sopenharmony_ci} 75