18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci NetWinder Floating Point Emulator 48c2ecf20Sopenharmony_ci (c) Rebel.com, 1998-1999 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci Direct questions, comments to Scott Bambrough <scottb@netwinder.org> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci*/ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef __FPA11_H__ 118c2ecf20Sopenharmony_ci#define __FPA11_H__ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#define GET_FPA11() ((FPA11 *)(¤t_thread_info()->fpstate)) 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* 168c2ecf20Sopenharmony_ci * The processes registers are always at the very top of the 8K 178c2ecf20Sopenharmony_ci * stack+task struct. Use the same method as 'current' uses to 188c2ecf20Sopenharmony_ci * reach them. 198c2ecf20Sopenharmony_ci */ 208c2ecf20Sopenharmony_ci#define GET_USERREG() ((struct pt_regs *)(THREAD_START_SP + (unsigned long)current_thread_info()) - 1) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include <linux/thread_info.h> 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* includes */ 258c2ecf20Sopenharmony_ci#include "fpsr.h" /* FP control and status register definitions */ 268c2ecf20Sopenharmony_ci#include "milieu.h" 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistruct roundingData { 298c2ecf20Sopenharmony_ci int8 mode; 308c2ecf20Sopenharmony_ci int8 precision; 318c2ecf20Sopenharmony_ci signed char exception; 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#include "softfloat.h" 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define typeNone 0x00 378c2ecf20Sopenharmony_ci#define typeSingle 0x01 388c2ecf20Sopenharmony_ci#define typeDouble 0x02 398c2ecf20Sopenharmony_ci#define typeExtended 0x03 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/* 428c2ecf20Sopenharmony_ci * This must be no more and no less than 12 bytes. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_citypedef union tagFPREG { 458c2ecf20Sopenharmony_ci float32 fSingle; 468c2ecf20Sopenharmony_ci float64 fDouble; 478c2ecf20Sopenharmony_ci#ifdef CONFIG_FPE_NWFPE_XP 488c2ecf20Sopenharmony_ci floatx80 fExtended; 498c2ecf20Sopenharmony_ci#else 508c2ecf20Sopenharmony_ci u32 padding[3]; 518c2ecf20Sopenharmony_ci#endif 528c2ecf20Sopenharmony_ci} __attribute__ ((packed,aligned(4))) FPREG; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci/* 558c2ecf20Sopenharmony_ci * FPA11 device model. 568c2ecf20Sopenharmony_ci * 578c2ecf20Sopenharmony_ci * This structure is exported to user space. Do not re-order. 588c2ecf20Sopenharmony_ci * Only add new stuff to the end, and do not change the size of 598c2ecf20Sopenharmony_ci * any element. Elements of this structure are used by user 608c2ecf20Sopenharmony_ci * space, and must match struct user_fp in <asm/user.h>. 618c2ecf20Sopenharmony_ci * We include the byte offsets below for documentation purposes. 628c2ecf20Sopenharmony_ci * 638c2ecf20Sopenharmony_ci * The size of this structure and FPREG are checked by fpmodule.c 648c2ecf20Sopenharmony_ci * on initialisation. If the rules have been broken, NWFPE will 658c2ecf20Sopenharmony_ci * not initialise. 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_citypedef struct tagFPA11 { 688c2ecf20Sopenharmony_ci/* 0 */ FPREG fpreg[8]; /* 8 floating point registers */ 698c2ecf20Sopenharmony_ci/* 96 */ FPSR fpsr; /* floating point status register */ 708c2ecf20Sopenharmony_ci/* 100 */ FPCR fpcr; /* floating point control register */ 718c2ecf20Sopenharmony_ci/* 104 */ unsigned char fType[8]; /* type of floating point value held in 728c2ecf20Sopenharmony_ci floating point registers. One of 738c2ecf20Sopenharmony_ci none, single, double or extended. */ 748c2ecf20Sopenharmony_ci/* 112 */ int initflag; /* this is special. The kernel guarantees 758c2ecf20Sopenharmony_ci to set it to 0 when a thread is launched, 768c2ecf20Sopenharmony_ci so we can use it to detect whether this 778c2ecf20Sopenharmony_ci instance of the emulator needs to be 788c2ecf20Sopenharmony_ci initialised. */ 798c2ecf20Sopenharmony_ci} __attribute__ ((packed,aligned(4))) FPA11; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciextern int8 SetRoundingMode(const unsigned int); 828c2ecf20Sopenharmony_ciextern int8 SetRoundingPrecision(const unsigned int); 838c2ecf20Sopenharmony_ciextern void nwfpe_init_fpa(union fp_state *fp); 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ciextern unsigned int EmulateAll(unsigned int opcode); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ciextern unsigned int EmulateCPDT(const unsigned int opcode); 888c2ecf20Sopenharmony_ciextern unsigned int EmulateCPDO(const unsigned int opcode); 898c2ecf20Sopenharmony_ciextern unsigned int EmulateCPRT(const unsigned int opcode); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci/* fpa11_cpdt.c */ 928c2ecf20Sopenharmony_ciextern unsigned int PerformLDF(const unsigned int opcode); 938c2ecf20Sopenharmony_ciextern unsigned int PerformSTF(const unsigned int opcode); 948c2ecf20Sopenharmony_ciextern unsigned int PerformLFM(const unsigned int opcode); 958c2ecf20Sopenharmony_ciextern unsigned int PerformSFM(const unsigned int opcode); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci/* single_cpdo.c */ 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ciextern unsigned int SingleCPDO(struct roundingData *roundData, 1008c2ecf20Sopenharmony_ci const unsigned int opcode, FPREG * rFd); 1018c2ecf20Sopenharmony_ci/* double_cpdo.c */ 1028c2ecf20Sopenharmony_ciextern unsigned int DoubleCPDO(struct roundingData *roundData, 1038c2ecf20Sopenharmony_ci const unsigned int opcode, FPREG * rFd); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* extneded_cpdo.c */ 1068c2ecf20Sopenharmony_ciextern unsigned int ExtendedCPDO(struct roundingData *roundData, 1078c2ecf20Sopenharmony_ci const unsigned int opcode, FPREG * rFd); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci#endif 110