linux-user/arm/nwfpe/fpa11.h | 126 --------- linux-user/arm/nwfpe/fpopcode.h | 390 --------------------------- linux-user/arm/nwfpe/fpsr.h | 107 -------- linux-user/qemu.h | 11 - linux-user/arm/cpu_loop.c | 59 ---- linux-user/arm/nwfpe/double_cpdo.c | 296 -------------------- linux-user/arm/nwfpe/extended_cpdo.c | 273 ------------------- linux-user/arm/nwfpe/fpa11.c | 270 ------------------- linux-user/arm/nwfpe/fpa11_cpdo.c | 113 -------- linux-user/arm/nwfpe/fpa11_cpdt.c | 382 -------------------------- linux-user/arm/nwfpe/fpa11_cprt.c | 284 ------------------- linux-user/arm/nwfpe/fpopcode.c | 91 ------- linux-user/arm/nwfpe/single_cpdo.c | 253 ----------------- linux-user/arm/meson.build | 2 - linux-user/arm/nwfpe/fpa11.inl | 50 ---- linux-user/arm/nwfpe/meson.build | 10 - 16 files changed, 2717 deletions(-) delete mode 100644 linux-user/arm/nwfpe/fpa11.h delete mode 100644 linux-user/arm/nwfpe/fpopcode.h delete mode 100644 linux-user/arm/nwfpe/fpsr.h delete mode 100644 linux-user/arm/nwfpe/double_cpdo.c delete mode 100644 linux-user/arm/nwfpe/extended_cpdo.c delete mode 100644 linux-user/arm/nwfpe/fpa11.c delete mode 100644 linux-user/arm/nwfpe/fpa11_cpdo.c delete mode 100644 linux-user/arm/nwfpe/fpa11_cpdt.c delete mode 100644 linux-user/arm/nwfpe/fpa11_cprt.c delete mode 100644 linux-user/arm/nwfpe/fpopcode.c delete mode 100644 linux-user/arm/nwfpe/single_cpdo.c delete mode 100644 linux-user/arm/nwfpe/fpa11.inl delete mode 100644 linux-user/arm/nwfpe/meson.build
This emulation is present in the linux kernel only for
a very restricted set of configurations:
config FPE_NWFPE
bool "NWFPE math emulation"
depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL
EABI is the default for all armv6 capable kernels, so this
isn't enabled in practice for some time.
GCC removed support for the FPA11 somewhere before gcc-5.
The code within nwfpe is not thread-safe, using several
global variables.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/arm/nwfpe/fpa11.h | 126 ---------
linux-user/arm/nwfpe/fpopcode.h | 390 ---------------------------
linux-user/arm/nwfpe/fpsr.h | 107 --------
linux-user/qemu.h | 11 -
linux-user/arm/cpu_loop.c | 59 ----
linux-user/arm/nwfpe/double_cpdo.c | 296 --------------------
linux-user/arm/nwfpe/extended_cpdo.c | 273 -------------------
linux-user/arm/nwfpe/fpa11.c | 270 -------------------
linux-user/arm/nwfpe/fpa11_cpdo.c | 113 --------
linux-user/arm/nwfpe/fpa11_cpdt.c | 382 --------------------------
linux-user/arm/nwfpe/fpa11_cprt.c | 284 -------------------
linux-user/arm/nwfpe/fpopcode.c | 91 -------
linux-user/arm/nwfpe/single_cpdo.c | 253 -----------------
linux-user/arm/meson.build | 2 -
linux-user/arm/nwfpe/fpa11.inl | 50 ----
linux-user/arm/nwfpe/meson.build | 10 -
16 files changed, 2717 deletions(-)
delete mode 100644 linux-user/arm/nwfpe/fpa11.h
delete mode 100644 linux-user/arm/nwfpe/fpopcode.h
delete mode 100644 linux-user/arm/nwfpe/fpsr.h
delete mode 100644 linux-user/arm/nwfpe/double_cpdo.c
delete mode 100644 linux-user/arm/nwfpe/extended_cpdo.c
delete mode 100644 linux-user/arm/nwfpe/fpa11.c
delete mode 100644 linux-user/arm/nwfpe/fpa11_cpdo.c
delete mode 100644 linux-user/arm/nwfpe/fpa11_cpdt.c
delete mode 100644 linux-user/arm/nwfpe/fpa11_cprt.c
delete mode 100644 linux-user/arm/nwfpe/fpopcode.c
delete mode 100644 linux-user/arm/nwfpe/single_cpdo.c
delete mode 100644 linux-user/arm/nwfpe/fpa11.inl
delete mode 100644 linux-user/arm/nwfpe/meson.build
diff --git a/linux-user/arm/nwfpe/fpa11.h b/linux-user/arm/nwfpe/fpa11.h
deleted file mode 100644
index d459c5da02..0000000000
--- a/linux-user/arm/nwfpe/fpa11.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.com, 1998-1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef FPA11_H
-#define FPA11_H
-
-#include "cpu.h"
-
-#define GET_FPA11() (qemufpa)
-
-/*
- * The processes registers are always at the very top of the 8K
- * stack+task struct. Use the same method as 'current' uses to
- * reach them.
- */
-extern CPUARMState *user_registers;
-
-#define GET_USERREG() (user_registers)
-
-/* Need task_struct */
-//#include <linux/sched.h>
-
-/* includes */
-#include "fpsr.h" /* FP control and status register definitions */
-#include "fpu/softfloat.h"
-
-#define typeNone 0x00
-#define typeSingle 0x01
-#define typeDouble 0x02
-#define typeExtended 0x03
-
-/*
- * This must be no more and no less than 12 bytes.
- */
-typedef union tagFPREG {
- floatx80 fExtended;
- float64 fDouble;
- float32 fSingle;
-} FPREG;
-
-/*
- * FPA11 device model.
- *
- * This structure is exported to user space. Do not re-order.
- * Only add new stuff to the end, and do not change the size of
- * any element. Elements of this structure are used by user
- * space, and must match struct user_fp in include/asm-arm/user.h.
- * We include the byte offsets below for documentation purposes.
- *
- * The size of this structure and FPREG are checked by fpmodule.c
- * on initialisation. If the rules have been broken, NWFPE will
- * not initialise.
- */
-typedef struct tagFPA11 {
-/* 0 */ FPREG fpreg[8]; /* 8 floating point registers */
-/* 96 */ FPSR fpsr; /* floating point status register */
-/* 100 */ FPCR fpcr; /* floating point control register */
-/* 104 */ unsigned char fType[8]; /* type of floating point value held in
- floating point registers. One of none
- single, double or extended. */
-/* 112 */ int initflag; /* this is special. The kernel guarantees
- to set it to 0 when a thread is launched,
- so we can use it to detect whether this
- instance of the emulator needs to be
- initialised. */
- float_status fp_status; /* QEMU float emulator status */
-} FPA11;
-
-extern FPA11* qemufpa;
-
-void resetFPA11(void);
-void SetRoundingMode(const unsigned int);
-void SetRoundingPrecision(const unsigned int);
-
-static inline unsigned int readRegister(unsigned int reg)
-{
- return (user_registers->regs[(reg)]);
-}
-
-static inline void writeRegister(unsigned int x, unsigned int y)
-{
-#if 0
- printf("writing %d to r%d\n",y,x);
-#endif
- user_registers->regs[(x)]=(y);
-}
-
-static inline void writeConditionCodes(unsigned int x)
-{
- cpsr_write(user_registers, x, CPSR_NZCV, CPSRWriteByInstr);
-}
-
-#define ARM_REG_PC 15
-
-unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs);
-
-unsigned int EmulateCPDO(const unsigned int);
-unsigned int EmulateCPDT(const unsigned int);
-unsigned int EmulateCPRT(const unsigned int);
-
-unsigned int SingleCPDO(const unsigned int opcode);
-unsigned int DoubleCPDO(const unsigned int opcode);
-unsigned int ExtendedCPDO(const unsigned int opcode);
-
-
-/* included only for get_user/put_user macros */
-#include "qemu.h"
-
-#endif
diff --git a/linux-user/arm/nwfpe/fpopcode.h b/linux-user/arm/nwfpe/fpopcode.h
deleted file mode 100644
index 06cd909850..0000000000
--- a/linux-user/arm/nwfpe/fpopcode.h
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.COM, 1998,1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef FPOPCODE_H
-#define FPOPCODE_H
-
-/*
-ARM Floating Point Instruction Classes
-| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-|c o n d|1 1 0 P|U|u|W|L| Rn |v| Fd |0|0|0|1| o f f s e t | CPDT
-|c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|0|1| o f f s e t | CPDT
-| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-|c o n d|1 1 1 0|a|b|c|d|e| Fn |j| Fd |0|0|0|1|f|g|h|0|i| Fm | CPDO
-|c o n d|1 1 1 0|a|b|c|L|e| Fn | Rd |0|0|0|1|f|g|h|1|i| Fm | CPRT
-|c o n d|1 1 1 0|a|b|c|1|e| Fn |1|1|1|1|0|0|0|1|f|g|h|1|i| Fm | comparisons
-| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-
-CPDT data transfer instructions
- LDF, STF, LFM, SFM
-
-CPDO dyadic arithmetic instructions
- ADF, MUF, SUF, RSF, DVF, RDF,
- POW, RPW, RMF, FML, FDV, FRD, POL
-
-CPDO monadic arithmetic instructions
- MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP,
- SIN, COS, TAN, ASN, ACS, ATN, URD, NRM
-
-CPRT joint arithmetic/data transfer instructions
- FIX (arithmetic followed by load/store)
- FLT (load/store followed by arithmetic)
- CMF, CNF CMFE, CNFE (comparisons)
- WFS, RFS (write/read floating point status register)
- WFC, RFC (write/read floating point control register)
-
-cond condition codes
-P pre/post index bit: 0 = postindex, 1 = preindex
-U up/down bit: 0 = stack grows down, 1 = stack grows up
-W write back bit: 1 = update base register (Rn)
-L load/store bit: 0 = store, 1 = load
-Rn base register
-Rd destination/source register
-Fd floating point destination register
-Fn floating point source register
-Fm floating point source register or floating point constant
-
-uv transfer length (TABLE 1)
-wx register count (TABLE 2)
-abcd arithmetic opcode (TABLES 3 & 4)
-ef destination size (rounding precision) (TABLE 5)
-gh rounding mode (TABLE 6)
-j dyadic/monadic bit: 0 = dyadic, 1 = monadic
-i constant bit: 1 = constant (TABLE 6)
-*/
-
-/*
-TABLE 1
-+-------------------------+---+---+---------+---------+
-| Precision | u | v | FPSR.EP | length |
-+-------------------------+---+---+---------+---------+
-| Single | 0 | 0 | x | 1 words |
-| Double | 1 | 1 | x | 2 words |
-| Extended | 1 | 1 | x | 3 words |
-| Packed decimal | 1 | 1 | 0 | 3 words |
-| Expanded packed decimal | 1 | 1 | 1 | 4 words |
-+-------------------------+---+---+---------+---------+
-Note: x = don't care
-*/
-
-/*
-TABLE 2
-+---+---+---------------------------------+
-| w | x | Number of registers to transfer |
-+---+---+---------------------------------+
-| 0 | 1 | 1 |
-| 1 | 0 | 2 |
-| 1 | 1 | 3 |
-| 0 | 0 | 4 |
-+---+---+---------------------------------+
-*/
-
-/*
-TABLE 3: Dyadic Floating Point Opcodes
-+---+---+---+---+----------+-----------------------+-----------------------+
-| a | b | c | d | Mnemonic | Description | Operation |
-+---+---+---+---+----------+-----------------------+-----------------------+
-| 0 | 0 | 0 | 0 | ADF | Add | Fd := Fn + Fm |
-| 0 | 0 | 0 | 1 | MUF | Multiply | Fd := Fn * Fm |
-| 0 | 0 | 1 | 0 | SUF | Subtract | Fd := Fn - Fm |
-| 0 | 0 | 1 | 1 | RSF | Reverse subtract | Fd := Fm - Fn |
-| 0 | 1 | 0 | 0 | DVF | Divide | Fd := Fn / Fm |
-| 0 | 1 | 0 | 1 | RDF | Reverse divide | Fd := Fm / Fn |
-| 0 | 1 | 1 | 0 | POW | Power | Fd := Fn ^ Fm |
-| 0 | 1 | 1 | 1 | RPW | Reverse power | Fd := Fm ^ Fn |
-| 1 | 0 | 0 | 0 | RMF | Remainder | Fd := IEEE rem(Fn/Fm) |
-| 1 | 0 | 0 | 1 | FML | Fast Multiply | Fd := Fn * Fm |
-| 1 | 0 | 1 | 0 | FDV | Fast Divide | Fd := Fn / Fm |
-| 1 | 0 | 1 | 1 | FRD | Fast reverse divide | Fd := Fm / Fn |
-| 1 | 1 | 0 | 0 | POL | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm) |
-| 1 | 1 | 0 | 1 | | undefined instruction | trap |
-| 1 | 1 | 1 | 0 | | undefined instruction | trap |
-| 1 | 1 | 1 | 1 | | undefined instruction | trap |
-+---+---+---+---+----------+-----------------------+-----------------------+
-Note: POW, RPW, POL are deprecated, and are available for backwards
- compatibility only.
-*/
-
-/*
-TABLE 4: Monadic Floating Point Opcodes
-+---+---+---+---+----------+-----------------------+-----------------------+
-| a | b | c | d | Mnemonic | Description | Operation |
-+---+---+---+---+----------+-----------------------+-----------------------+
-| 0 | 0 | 0 | 0 | MVF | Move | Fd := Fm |
-| 0 | 0 | 0 | 1 | MNF | Move negated | Fd := - Fm |
-| 0 | 0 | 1 | 0 | ABS | Absolute value | Fd := abs(Fm) |
-| 0 | 0 | 1 | 1 | RND | Round to integer | Fd := int(Fm) |
-| 0 | 1 | 0 | 0 | SQT | Square root | Fd := sqrt(Fm) |
-| 0 | 1 | 0 | 1 | LOG | Log base 10 | Fd := log10(Fm) |
-| 0 | 1 | 1 | 0 | LGN | Log base e | Fd := ln(Fm) |
-| 0 | 1 | 1 | 1 | EXP | Exponent | Fd := e ^ Fm |
-| 1 | 0 | 0 | 0 | SIN | Sine | Fd := sin(Fm) |
-| 1 | 0 | 0 | 1 | COS | Cosine | Fd := cos(Fm) |
-| 1 | 0 | 1 | 0 | TAN | Tangent | Fd := tan(Fm) |
-| 1 | 0 | 1 | 1 | ASN | Arc Sine | Fd := arcsin(Fm) |
-| 1 | 1 | 0 | 0 | ACS | Arc Cosine | Fd := arccos(Fm) |
-| 1 | 1 | 0 | 1 | ATN | Arc Tangent | Fd := arctan(Fm) |
-| 1 | 1 | 1 | 0 | URD | Unnormalized round | Fd := int(Fm) |
-| 1 | 1 | 1 | 1 | NRM | Normalize | Fd := norm(Fm) |
-+---+---+---+---+----------+-----------------------+-----------------------+
-Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are
- available for backwards compatibility only.
-*/
-
-/*
-TABLE 5
-+-------------------------+---+---+
-| Rounding Precision | e | f |
-+-------------------------+---+---+
-| IEEE Single precision | 0 | 0 |
-| IEEE Double precision | 0 | 1 |
-| IEEE Extended precision | 1 | 0 |
-| undefined (trap) | 1 | 1 |
-+-------------------------+---+---+
-*/
-
-/*
-TABLE 5
-+---------------------------------+---+---+
-| Rounding Mode | g | h |
-+---------------------------------+---+---+
-| Round to nearest (default) | 0 | 0 |
-| Round toward plus infinity | 0 | 1 |
-| Round toward negative infinity | 1 | 0 |
-| Round toward zero | 1 | 1 |
-+---------------------------------+---+---+
-*/
-
-/*
-===
-=== Definitions for load and store instructions
-===
-*/
-
-/* bit masks */
-#define BIT_PREINDEX 0x01000000
-#define BIT_UP 0x00800000
-#define BIT_WRITE_BACK 0x00200000
-#define BIT_LOAD 0x00100000
-
-/* masks for load/store */
-#define MASK_CPDT 0x0c000000 /* data processing opcode */
-#define MASK_OFFSET 0x000000ff
-#define MASK_TRANSFER_LENGTH 0x00408000
-#define MASK_REGISTER_COUNT MASK_TRANSFER_LENGTH
-#define MASK_COPROCESSOR 0x00000f00
-
-/* Tests for transfer length */
-#define TRANSFER_SINGLE 0x00000000
-#define TRANSFER_DOUBLE 0x00008000
-#define TRANSFER_EXTENDED 0x00400000
-#define TRANSFER_PACKED MASK_TRANSFER_LENGTH
-
-/* Get the coprocessor number from the opcode. */
-#define getCoprocessorNumber(opcode) ((opcode & MASK_COPROCESSOR) >> 8)
-
-/* Get the offset from the opcode. */
-#define getOffset(opcode) (opcode & MASK_OFFSET)
-
-/* Tests for specific data transfer load/store opcodes. */
-#define TEST_OPCODE(opcode,mask) (((opcode) & (mask)) == (mask))
-
-#define LOAD_OP(opcode) TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD)
-#define STORE_OP(opcode) ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT)
-
-#define LDF_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
-#define LFM_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
-#define STF_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
-#define SFM_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
-
-#define PREINDEXED(opcode) ((opcode & BIT_PREINDEX) != 0)
-#define POSTINDEXED(opcode) ((opcode & BIT_PREINDEX) == 0)
-#define BIT_UP_SET(opcode) ((opcode & BIT_UP) != 0)
-#define BIT_UP_CLEAR(opcode) ((opcode & BIT_DOWN) == 0)
-#define WRITE_BACK(opcode) ((opcode & BIT_WRITE_BACK) != 0)
-#define LOAD(opcode) ((opcode & BIT_LOAD) != 0)
-#define STORE(opcode) ((opcode & BIT_LOAD) == 0)
-
-/*
-===
-=== Definitions for arithmetic instructions
-===
-*/
-/* bit masks */
-#define BIT_MONADIC 0x00008000
-#define BIT_CONSTANT 0x00000008
-
-#define CONSTANT_FM(opcode) ((opcode & BIT_CONSTANT) != 0)
-#define MONADIC_INSTRUCTION(opcode) ((opcode & BIT_MONADIC) != 0)
-
-/* instruction identification masks */
-#define MASK_CPDO 0x0e000000 /* arithmetic opcode */
-#define MASK_ARITHMETIC_OPCODE 0x00f08000
-#define MASK_DESTINATION_SIZE 0x00080080
-
-/* dyadic arithmetic opcodes. */
-#define ADF_CODE 0x00000000
-#define MUF_CODE 0x00100000
-#define SUF_CODE 0x00200000
-#define RSF_CODE 0x00300000
-#define DVF_CODE 0x00400000
-#define RDF_CODE 0x00500000
-#define POW_CODE 0x00600000
-#define RPW_CODE 0x00700000
-#define RMF_CODE 0x00800000
-#define FML_CODE 0x00900000
-#define FDV_CODE 0x00a00000
-#define FRD_CODE 0x00b00000
-#define POL_CODE 0x00c00000
-/* 0x00d00000 is an invalid dyadic arithmetic opcode */
-/* 0x00e00000 is an invalid dyadic arithmetic opcode */
-/* 0x00f00000 is an invalid dyadic arithmetic opcode */
-
-/* monadic arithmetic opcodes. */
-#define MVF_CODE 0x00008000
-#define MNF_CODE 0x00108000
-#define ABS_CODE 0x00208000
-#define RND_CODE 0x00308000
-#define SQT_CODE 0x00408000
-#define LOG_CODE 0x00508000
-#define LGN_CODE 0x00608000
-#define EXP_CODE 0x00708000
-#define SIN_CODE 0x00808000
-#define COS_CODE 0x00908000
-#define TAN_CODE 0x00a08000
-#define ASN_CODE 0x00b08000
-#define ACS_CODE 0x00c08000
-#define ATN_CODE 0x00d08000
-#define URD_CODE 0x00e08000
-#define NRM_CODE 0x00f08000
-
-/*
-===
-=== Definitions for register transfer and comparison instructions
-===
-*/
-
-#define MASK_CPRT 0x0e000010 /* register transfer opcode */
-#define MASK_CPRT_CODE 0x00f00000
-#define FLT_CODE 0x00000000
-#define FIX_CODE 0x00100000
-#define WFS_CODE 0x00200000
-#define RFS_CODE 0x00300000
-#define WFC_CODE 0x00400000
-#define RFC_CODE 0x00500000
-#define CMF_CODE 0x00900000
-#define CNF_CODE 0x00b00000
-#define CMFE_CODE 0x00d00000
-#define CNFE_CODE 0x00f00000
-
-/*
-===
-=== Common definitions
-===
-*/
-
-/* register masks */
-#define MASK_Rd 0x0000f000
-#define MASK_Rn 0x000f0000
-#define MASK_Fd 0x00007000
-#define MASK_Fm 0x00000007
-#define MASK_Fn 0x00070000
-
-/* condition code masks */
-#define CC_MASK 0xf0000000
-#define CC_NEGATIVE 0x80000000
-#define CC_ZERO 0x40000000
-#define CC_CARRY 0x20000000
-#define CC_OVERFLOW 0x10000000
-#define CC_EQ 0x00000000
-#define CC_NE 0x10000000
-#define CC_CS 0x20000000
-#define CC_HS CC_CS
-#define CC_CC 0x30000000
-#define CC_LO CC_CC
-#define CC_MI 0x40000000
-#define CC_PL 0x50000000
-#define CC_VS 0x60000000
-#define CC_VC 0x70000000
-#define CC_HI 0x80000000
-#define CC_LS 0x90000000
-#define CC_GE 0xa0000000
-#define CC_LT 0xb0000000
-#define CC_GT 0xc0000000
-#define CC_LE 0xd0000000
-#define CC_AL 0xe0000000
-#define CC_NV 0xf0000000
-
-/* rounding masks/values */
-#define MASK_ROUNDING_MODE 0x00000060
-#define ROUND_TO_NEAREST 0x00000000
-#define ROUND_TO_PLUS_INFINITY 0x00000020
-#define ROUND_TO_MINUS_INFINITY 0x00000040
-#define ROUND_TO_ZERO 0x00000060
-
-#define MASK_ROUNDING_PRECISION 0x00080080
-#define ROUND_SINGLE 0x00000000
-#define ROUND_DOUBLE 0x00000080
-#define ROUND_EXTENDED 0x00080000
-
-/* Get the condition code from the opcode. */
-#define getCondition(opcode) (opcode >> 28)
-
-/* Get the source register from the opcode. */
-#define getRn(opcode) ((opcode & MASK_Rn) >> 16)
-
-/* Get the destination floating point register from the opcode. */
-#define getFd(opcode) ((opcode & MASK_Fd) >> 12)
-
-/* Get the first source floating point register from the opcode. */
-#define getFn(opcode) ((opcode & MASK_Fn) >> 16)
-
-/* Get the second source floating point register from the opcode. */
-#define getFm(opcode) (opcode & MASK_Fm)
-
-/* Get the destination register from the opcode. */
-#define getRd(opcode) ((opcode & MASK_Rd) >> 12)
-
-/* Get the rounding mode from the opcode. */
-#define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5)
-
-extern const floatx80 floatx80Constant[];
-extern const float64 float64Constant[];
-extern const float32 float32Constant[];
-
-static inline floatx80 getExtendedConstant(const unsigned int nIndex)
-{
- return floatx80Constant[nIndex];
-}
-
-static inline float64 getDoubleConstant(const unsigned int nIndex)
-{
- return float64Constant[nIndex];
-}
-
-static inline float32 getSingleConstant(const unsigned int nIndex)
-{
- return float32Constant[nIndex];
-}
-
-unsigned int getRegisterCount(const unsigned int opcode);
-unsigned int getDestinationSize(const unsigned int opcode);
-
-#endif
diff --git a/linux-user/arm/nwfpe/fpsr.h b/linux-user/arm/nwfpe/fpsr.h
deleted file mode 100644
index 8c978f0b8f..0000000000
--- a/linux-user/arm/nwfpe/fpsr.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.com, 1998-1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef FPSR_H
-#define FPSR_H
-
-/*
-The FPSR is a 32 bit register consisting of 4 parts, each exactly
-one byte.
-
- SYSTEM ID
- EXCEPTION TRAP ENABLE BYTE
- SYSTEM CONTROL BYTE
- CUMULATIVE EXCEPTION FLAGS BYTE
-
-The FPCR is a 32 bit register consisting of bit flags.
-*/
-
-/* SYSTEM ID
-------------
-Note: the system id byte is read only */
-
-typedef unsigned int FPSR; /* type for floating point status register */
-typedef unsigned int FPCR; /* type for floating point control register */
-
-#define MASK_SYSID 0xff000000
-#define BIT_HARDWARE 0x80000000
-#define FP_EMULATOR 0x01000000 /* System ID for emulator */
-#define FP_ACCELERATOR 0x81000000 /* System ID for FPA11 */
-
-/* EXCEPTION TRAP ENABLE BYTE
------------------------------ */
-
-#define MASK_TRAP_ENABLE 0x00ff0000
-#define MASK_TRAP_ENABLE_STRICT 0x001f0000
-#define BIT_IXE 0x00100000 /* inexact exception enable */
-#define BIT_UFE 0x00080000 /* underflow exception enable */
-#define BIT_OFE 0x00040000 /* overflow exception enable */
-#define BIT_DZE 0x00020000 /* divide by zero exception enable */
-#define BIT_IOE 0x00010000 /* invalid operation exception enable */
-
-/* SYSTEM CONTROL BYTE
----------------------- */
-
-#define MASK_SYSTEM_CONTROL 0x0000ff00
-#define MASK_TRAP_STRICT 0x00001f00
-
-#define BIT_AC 0x00001000 /* use alternative C-flag definition
- for compares */
-#define BIT_EP 0x00000800 /* use expanded packed decimal format */
-#define BIT_SO 0x00000400 /* select synchronous operation of FPA */
-#define BIT_NE 0x00000200 /* NaN exception bit */
-#define BIT_ND 0x00000100 /* no denormalized numbers bit */
-
-/* CUMULATIVE EXCEPTION FLAGS BYTE
----------------------------------- */
-
-#define MASK_EXCEPTION_FLAGS 0x000000ff
-#define MASK_EXCEPTION_FLAGS_STRICT 0x0000001f
-
-#define BIT_IXC 0x00000010 /* inexact exception flag */
-#define BIT_UFC 0x00000008 /* underflow exception flag */
-#define BIT_OFC 0x00000004 /* overfloat exception flag */
-#define BIT_DZC 0x00000002 /* divide by zero exception flag */
-#define BIT_IOC 0x00000001 /* invalid operation exception flag */
-
-/* Floating Point Control Register
-----------------------------------*/
-
-#define BIT_RU 0x80000000 /* rounded up bit */
-#define BIT_IE 0x10000000 /* inexact bit */
-#define BIT_MO 0x08000000 /* mantissa overflow bit */
-#define BIT_EO 0x04000000 /* exponent overflow bit */
-#define BIT_SB 0x00000800 /* store bounce */
-#define BIT_AB 0x00000400 /* arithmetic bounce */
-#define BIT_RE 0x00000200 /* rounding exception */
-#define BIT_DA 0x00000100 /* disable FPA */
-
-#define MASK_OP 0x00f08010 /* AU operation code */
-#define MASK_PR 0x00080080 /* AU precision */
-#define MASK_S1 0x00070000 /* AU source register 1 */
-#define MASK_S2 0x00000007 /* AU source register 2 */
-#define MASK_DS 0x00007000 /* AU destination register */
-#define MASK_RM 0x00000060 /* AU rounding mode */
-#define MASK_ALU 0x9cfff2ff /* only ALU can write these bits */
-#define MASK_RESET 0x00000d00 /* bits set on reset, all others cleared */
-#define MASK_WFC MASK_RESET
-#define MASK_RFC ~MASK_RESET
-
-#endif
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index cfe5f45fc4..21afce4088 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -87,11 +87,6 @@ struct vm86_saved_state {
};
#endif
-#if defined(TARGET_ARM) && defined(TARGET_ABI32)
-/* FPU emulator */
-#include "nwfpe/fpa11.h"
-#endif
-
struct emulated_sigtable {
int pending; /* true if signal is pending */
target_siginfo_t info;
@@ -99,12 +94,6 @@ struct emulated_sigtable {
struct TaskState {
pid_t ts_tid; /* tid (or pid) of this task */
-#ifdef TARGET_ARM
-# ifdef TARGET_ABI32
- /* FPA state */
- FPA11 fpa;
-# endif
-#endif
#if defined(TARGET_ARM) || defined(TARGET_RISCV)
int swi_errno;
#endif
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index 19874f4c72..36f82541c7 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -212,61 +212,6 @@ static bool insn_is_linux_bkpt(uint32_t opcode, bool is_thumb)
}
}
-static bool emulate_arm_fpa11(CPUARMState *env, uint32_t opcode)
-{
- TaskState *ts = get_task_state(env_cpu(env));
- int rc = EmulateAll(opcode, &ts->fpa, env);
- int raise, enabled;
-
- if (rc == 0) {
- /* Illegal instruction */
- return false;
- }
- if (rc > 0) {
- /* Everything ok. */
- env->regs[15] += 4;
- return true;
- }
-
- /* FP exception */
- rc = -rc;
- raise = 0;
-
- /* Translate softfloat flags to FPSR flags */
- if (rc & float_flag_invalid) {
- raise |= BIT_IOC;
- }
- if (rc & float_flag_divbyzero) {
- raise |= BIT_DZC;
- }
- if (rc & float_flag_overflow) {
- raise |= BIT_OFC;
- }
- if (rc & float_flag_underflow) {
- raise |= BIT_UFC;
- }
- if (rc & float_flag_inexact) {
- raise |= BIT_IXC;
- }
-
- /* Accumulate unenabled exceptions */
- enabled = ts->fpa.fpsr >> 16;
- ts->fpa.fpsr |= raise & ~enabled;
-
- if (raise & enabled) {
- /*
- * The kernel's nwfpe emulator does not pass a real si_code.
- * It merely uses send_sig(SIGFPE, current, 1), which results in
- * __send_signal() filling out SI_KERNEL with pid and uid 0 (under
- * the "SEND_SIG_PRIV" case). That's what our force_sig() does.
- */
- force_sig(TARGET_SIGFPE);
- } else {
- env->regs[15] += 4;
- }
- return true;
-}
-
void cpu_loop(CPUARMState *env)
{
CPUState *cs = env_cpu(env);
@@ -302,10 +247,6 @@ void cpu_loop(CPUARMState *env)
goto excp_debug;
}
- if (!env->thumb && emulate_arm_fpa11(env, opcode)) {
- break;
- }
-
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN,
env->regs[15]);
}
diff --git a/linux-user/arm/nwfpe/double_cpdo.c b/linux-user/arm/nwfpe/double_cpdo.c
deleted file mode 100644
index d45ece2e2f..0000000000
--- a/linux-user/arm/nwfpe/double_cpdo.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.COM, 1998,1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "fpa11.h"
-#include "fpu/softfloat.h"
-#include "fpopcode.h"
-
-float64 float64_exp(float64 Fm);
-float64 float64_ln(float64 Fm);
-float64 float64_sin(float64 rFm);
-float64 float64_cos(float64 rFm);
-float64 float64_arcsin(float64 rFm);
-float64 float64_arctan(float64 rFm);
-float64 float64_log(float64 rFm);
-float64 float64_tan(float64 rFm);
-float64 float64_arccos(float64 rFm);
-float64 float64_pow(float64 rFn,float64 rFm);
-float64 float64_pol(float64 rFn,float64 rFm);
-
-unsigned int DoubleCPDO(const unsigned int opcode)
-{
- FPA11 *fpa11 = GET_FPA11();
- float64 rFm, rFn = float64_zero;
- unsigned int Fd, Fm, Fn, nRc = 1;
-
- //printk("DoubleCPDO(0x%08x)\n",opcode);
-
- Fm = getFm(opcode);
- if (CONSTANT_FM(opcode))
- {
- rFm = getDoubleConstant(Fm);
- }
- else
- {
- switch (fpa11->fType[Fm])
- {
- case typeSingle:
- rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
- break;
-
- case typeDouble:
- rFm = fpa11->fpreg[Fm].fDouble;
- break;
-
- case typeExtended:
- // !! patb
- //printk("not implemented! why not?\n");
- //!! ScottB
- // should never get here, if extended involved
- // then other operand should be promoted then
- // ExtendedCPDO called.
- break;
-
- default: return 0;
- }
- }
-
- if (!MONADIC_INSTRUCTION(opcode))
- {
- Fn = getFn(opcode);
- switch (fpa11->fType[Fn])
- {
- case typeSingle:
- rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
- break;
-
- case typeDouble:
- rFn = fpa11->fpreg[Fn].fDouble;
- break;
-
- default: return 0;
- }
- }
-
- Fd = getFd(opcode);
- /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
- switch (opcode & MASK_ARITHMETIC_OPCODE)
- {
- /* dyadic opcodes */
- case ADF_CODE:
- fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm, &fpa11->fp_status);
- break;
-
- case MUF_CODE:
- case FML_CODE:
- fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm, &fpa11->fp_status);
- break;
-
- case SUF_CODE:
- fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm, &fpa11->fp_status);
- break;
-
- case RSF_CODE:
- fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn, &fpa11->fp_status);
- break;
-
- case DVF_CODE:
- case FDV_CODE:
- fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm, &fpa11->fp_status);
- break;
-
- case RDF_CODE:
- case FRD_CODE:
- fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn, &fpa11->fp_status);
- break;
-
-#if 0
- case POW_CODE:
- fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
- break;
-
- case RPW_CODE:
- fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
- break;
-#endif
-
- case RMF_CODE:
- fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm, &fpa11->fp_status);
- break;
-
-#if 0
- case POL_CODE:
- fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
- break;
-#endif
-
- /* monadic opcodes */
- case MVF_CODE:
- fpa11->fpreg[Fd].fDouble = rFm;
- break;
-
- case MNF_CODE:
- {
- unsigned int *p = (unsigned int*)&rFm;
-#if HOST_BIG_ENDIAN
- p[0] ^= 0x80000000;
-#else
- p[1] ^= 0x80000000;
-#endif
- fpa11->fpreg[Fd].fDouble = rFm;
- }
- break;
-
- case ABS_CODE:
- {
- unsigned int *p = (unsigned int*)&rFm;
-#if HOST_BIG_ENDIAN
- p[0] &= 0x7fffffff;
-#else
- p[1] &= 0x7fffffff;
-#endif
- fpa11->fpreg[Fd].fDouble = rFm;
- }
- break;
-
- case RND_CODE:
- case URD_CODE:
- fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm, &fpa11->fp_status);
- break;
-
- case SQT_CODE:
- fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm, &fpa11->fp_status);
- break;
-
-#if 0
- case LOG_CODE:
- fpa11->fpreg[Fd].fDouble = float64_log(rFm);
- break;
-
- case LGN_CODE:
- fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
- break;
-
- case EXP_CODE:
- fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
- break;
-
- case SIN_CODE:
- fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
- break;
-
- case COS_CODE:
- fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
- break;
-
- case TAN_CODE:
- fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
- break;
-
- case ASN_CODE:
- fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
- break;
-
- case ACS_CODE:
- fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
- break;
-
- case ATN_CODE:
- fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
- break;
-#endif
-
- case NRM_CODE:
- break;
-
- default:
- {
- nRc = 0;
- }
- }
-
- if (0 != nRc) fpa11->fType[Fd] = typeDouble;
- return nRc;
-}
-
-#if 0
-float64 float64_exp(float64 rFm)
-{
- return rFm;
-//series
-}
-
-float64 float64_ln(float64 rFm)
-{
- return rFm;
-//series
-}
-
-float64 float64_sin(float64 rFm)
-{
- return rFm;
-//series
-}
-
-float64 float64_cos(float64 rFm)
-{
- return rFm;
- //series
-}
-
-#if 0
-float64 float64_arcsin(float64 rFm)
-{
-//series
-}
-
-float64 float64_arctan(float64 rFm)
-{
- //series
-}
-#endif
-
-float64 float64_log(float64 rFm)
-{
- return float64_div(float64_ln(rFm),getDoubleConstant(7));
-}
-
-float64 float64_tan(float64 rFm)
-{
- return float64_div(float64_sin(rFm),float64_cos(rFm));
-}
-
-float64 float64_arccos(float64 rFm)
-{
-return rFm;
- //return float64_sub(halfPi,float64_arcsin(rFm));
-}
-
-float64 float64_pow(float64 rFn,float64 rFm)
-{
- return float64_exp(float64_mul(rFm,float64_ln(rFn)));
-}
-
-float64 float64_pol(float64 rFn,float64 rFm)
-{
- return float64_arctan(float64_div(rFn,rFm));
-}
-#endif
diff --git a/linux-user/arm/nwfpe/extended_cpdo.c b/linux-user/arm/nwfpe/extended_cpdo.c
deleted file mode 100644
index 1c8a412292..0000000000
--- a/linux-user/arm/nwfpe/extended_cpdo.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.COM, 1998,1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "fpa11.h"
-#include "fpu/softfloat.h"
-#include "fpopcode.h"
-
-floatx80 floatx80_exp(floatx80 Fm);
-floatx80 floatx80_ln(floatx80 Fm);
-floatx80 floatx80_sin(floatx80 rFm);
-floatx80 floatx80_cos(floatx80 rFm);
-floatx80 floatx80_arcsin(floatx80 rFm);
-floatx80 floatx80_arctan(floatx80 rFm);
-floatx80 floatx80_log(floatx80 rFm);
-floatx80 floatx80_tan(floatx80 rFm);
-floatx80 floatx80_arccos(floatx80 rFm);
-floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm);
-floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm);
-
-unsigned int ExtendedCPDO(const unsigned int opcode)
-{
- FPA11 *fpa11 = GET_FPA11();
- floatx80 rFm, rFn;
- unsigned int Fd, Fm, Fn, nRc = 1;
-
- //printk("ExtendedCPDO(0x%08x)\n",opcode);
-
- Fm = getFm(opcode);
- if (CONSTANT_FM(opcode))
- {
- rFm = getExtendedConstant(Fm);
- }
- else
- {
- switch (fpa11->fType[Fm])
- {
- case typeSingle:
- rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
- break;
-
- case typeDouble:
- rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status);
- break;
-
- case typeExtended:
- rFm = fpa11->fpreg[Fm].fExtended;
- break;
-
- default: return 0;
- }
- }
-
- if (!MONADIC_INSTRUCTION(opcode))
- {
- Fn = getFn(opcode);
- switch (fpa11->fType[Fn])
- {
- case typeSingle:
- rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
- break;
-
- case typeDouble:
- rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
- break;
-
- case typeExtended:
- rFn = fpa11->fpreg[Fn].fExtended;
- break;
-
- default: return 0;
- }
- }
-
- Fd = getFd(opcode);
- switch (opcode & MASK_ARITHMETIC_OPCODE)
- {
- /* dyadic opcodes */
- case ADF_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm, &fpa11->fp_status);
- break;
-
- case MUF_CODE:
- case FML_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm, &fpa11->fp_status);
- break;
-
- case SUF_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm, &fpa11->fp_status);
- break;
-
- case RSF_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn, &fpa11->fp_status);
- break;
-
- case DVF_CODE:
- case FDV_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm, &fpa11->fp_status);
- break;
-
- case RDF_CODE:
- case FRD_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn, &fpa11->fp_status);
- break;
-
-#if 0
- case POW_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm);
- break;
-
- case RPW_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn);
- break;
-#endif
-
- case RMF_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm, &fpa11->fp_status);
- break;
-
-#if 0
- case POL_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm);
- break;
-#endif
-
- /* monadic opcodes */
- case MVF_CODE:
- fpa11->fpreg[Fd].fExtended = rFm;
- break;
-
- case MNF_CODE:
- rFm.high ^= 0x8000;
- fpa11->fpreg[Fd].fExtended = rFm;
- break;
-
- case ABS_CODE:
- rFm.high &= 0x7fff;
- fpa11->fpreg[Fd].fExtended = rFm;
- break;
-
- case RND_CODE:
- case URD_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm, &fpa11->fp_status);
- break;
-
- case SQT_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm, &fpa11->fp_status);
- break;
-
-#if 0
- case LOG_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_log(rFm);
- break;
-
- case LGN_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm);
- break;
-
- case EXP_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm);
- break;
-
- case SIN_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm);
- break;
-
- case COS_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm);
- break;
-
- case TAN_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm);
- break;
-
- case ASN_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm);
- break;
-
- case ACS_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm);
- break;
-
- case ATN_CODE:
- fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm);
- break;
-#endif
-
- case NRM_CODE:
- break;
-
- default:
- {
- nRc = 0;
- }
- }
-
- if (0 != nRc) fpa11->fType[Fd] = typeExtended;
- return nRc;
-}
-
-#if 0
-floatx80 floatx80_exp(floatx80 Fm)
-{
-//series
-}
-
-floatx80 floatx80_ln(floatx80 Fm)
-{
-//series
-}
-
-floatx80 floatx80_sin(floatx80 rFm)
-{
-//series
-}
-
-floatx80 floatx80_cos(floatx80 rFm)
-{
-//series
-}
-
-floatx80 floatx80_arcsin(floatx80 rFm)
-{
-//series
-}
-
-floatx80 floatx80_arctan(floatx80 rFm)
-{
- //series
-}
-
-floatx80 floatx80_log(floatx80 rFm)
-{
- return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7));
-}
-
-floatx80 floatx80_tan(floatx80 rFm)
-{
- return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm));
-}
-
-floatx80 floatx80_arccos(floatx80 rFm)
-{
- //return floatx80_sub(halfPi,floatx80_arcsin(rFm));
-}
-
-floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm)
-{
- return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn)));
-}
-
-floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm)
-{
- return floatx80_arctan(floatx80_div(rFn,rFm));
-}
-#endif
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
deleted file mode 100644
index 0f1afbd91d..0000000000
--- a/linux-user/arm/nwfpe/fpa11.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.COM, 1998,1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "fpa11.h"
-
-#include "fpopcode.h"
-
-//#include "fpmodule.h"
-//#include "fpmodule.inl"
-
-//#include <asm/system.h>
-
-
-FPA11* qemufpa = NULL;
-CPUARMState* user_registers;
-
-/* Reset the FPA11 chip. Called to initialize and reset the emulator. */
-void resetFPA11(void)
-{
- int i;
- FPA11 *fpa11 = GET_FPA11();
-
- /* initialize the register type array */
- for (i=0;i<=7;i++)
- {
- fpa11->fType[i] = typeNone;
- }
-
- /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
- fpa11->fpsr = FP_EMULATOR | BIT_AC;
-
- /* FPCR: set SB, AB and DA bits, clear all others */
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr = MASK_RESET;
-#endif
-
- /*
- * Real FPA11 hardware does not handle NaNs, but always takes an
- * exception for them to be software-emulated (ARM7500FE datasheet
- * section 10.4). There is no documented architectural requirement
- * for NaN propagation rules and it will depend on how the OS
- * level software emulation opted to do it. We here use prop_s_ab
- * which matches the later VFP hardware choice and how QEMU's
- * fpa11 emulation has worked in the past. The real Linux kernel
- * does something slightly different: arch/arm/nwfpe/softfloat-specialize
- * propagateFloat64NaN() has the curious behaviour that it prefers
- * the QNaN over the SNaN, but if both are QNaN it picks A and
- * if both are SNaN it picks B. In theory we could add this as
- * a NaN propagation rule, but in practice FPA11 emulation is so
- * close to totally dead that it's not worth trying to match it at
- * this late date.
- */
- set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
- /*
- * Use the same default NaN value as Arm VFP. This doesn't match
- * the Linux kernel's nwfpe emulation, which uses an all-1s value.
- */
- set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
-}
-
-void SetRoundingMode(const unsigned int opcode)
-{
- int rounding_mode;
- FPA11 *fpa11 = GET_FPA11();
-
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr &= ~MASK_ROUNDING_MODE;
-#endif
- switch (opcode & MASK_ROUNDING_MODE)
- {
- default:
- case ROUND_TO_NEAREST:
- rounding_mode = float_round_nearest_even;
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr |= ROUND_TO_NEAREST;
-#endif
- break;
-
- case ROUND_TO_PLUS_INFINITY:
- rounding_mode = float_round_up;
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
-#endif
- break;
-
- case ROUND_TO_MINUS_INFINITY:
- rounding_mode = float_round_down;
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
-#endif
- break;
-
- case ROUND_TO_ZERO:
- rounding_mode = float_round_to_zero;
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr |= ROUND_TO_ZERO;
-#endif
- break;
- }
- set_float_rounding_mode(rounding_mode, &fpa11->fp_status);
-}
-
-void SetRoundingPrecision(const unsigned int opcode)
-{
- FloatX80RoundPrec rounding_precision;
- FPA11 *fpa11 = GET_FPA11();
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
-#endif
- switch (opcode & MASK_ROUNDING_PRECISION) {
- case ROUND_SINGLE:
- rounding_precision = floatx80_precision_s;
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr |= ROUND_SINGLE;
-#endif
- break;
-
- case ROUND_DOUBLE:
- rounding_precision = floatx80_precision_d;
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr |= ROUND_DOUBLE;
-#endif
- break;
-
- case ROUND_EXTENDED:
- rounding_precision = floatx80_precision_x;
-#ifdef MAINTAIN_FPCR
- fpa11->fpcr |= ROUND_EXTENDED;
-#endif
- break;
-
- default:
- rounding_precision = floatx80_precision_x;
- break;
- }
- set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status);
-}
-
-/* Emulate the instruction in the opcode. */
-/* ??? This is not thread safe. */
-unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
-{
- unsigned int nRc = 0;
-// unsigned long flags;
- FPA11 *fpa11;
- unsigned int cp;
-// save_flags(flags); sti();
-
- /* Check that this is really an FPA11 instruction: the coprocessor
- * field in bits [11:8] must be 1 or 2.
- */
- cp = (opcode >> 8) & 0xf;
- if (cp != 1 && cp != 2) {
- return 0;
- }
-
- qemufpa=qfpa;
- user_registers=qregs;
-
-#if 0
- fprintf(stderr,"emulating FP insn 0x%08x, PC=0x%08x\n",
- opcode, qregs[ARM_REG_PC]);
-#endif
- fpa11 = GET_FPA11();
-
- if (fpa11->initflag == 0) /* good place for __builtin_expect */
- {
- resetFPA11();
- SetRoundingMode(ROUND_TO_NEAREST);
- SetRoundingPrecision(ROUND_EXTENDED);
- fpa11->initflag = 1;
- }
-
- set_float_exception_flags(0, &fpa11->fp_status);
-
- if (TEST_OPCODE(opcode,MASK_CPRT))
- {
- //fprintf(stderr,"emulating CPRT\n");
- /* Emulate conversion opcodes. */
- /* Emulate register transfer opcodes. */
- /* Emulate comparison opcodes. */
- nRc = EmulateCPRT(opcode);
- }
- else if (TEST_OPCODE(opcode,MASK_CPDO))
- {
- //fprintf(stderr,"emulating CPDO\n");
- /* Emulate monadic arithmetic opcodes. */
- /* Emulate dyadic arithmetic opcodes. */
- nRc = EmulateCPDO(opcode);
- }
- else if (TEST_OPCODE(opcode,MASK_CPDT))
- {
- //fprintf(stderr,"emulating CPDT\n");
- /* Emulate load/store opcodes. */
- /* Emulate load/store multiple opcodes. */
- nRc = EmulateCPDT(opcode);
- }
- else
- {
- /* Invalid instruction detected. Return FALSE. */
- nRc = 0;
- }
-
-// restore_flags(flags);
- if(nRc == 1 && get_float_exception_flags(&fpa11->fp_status))
- {
- //printf("fef 0x%x\n",float_exception_flags);
- nRc = -get_float_exception_flags(&fpa11->fp_status);
- }
-
- //printf("returning %d\n",nRc);
- return(nRc);
-}
-
-#if 0
-unsigned int EmulateAll1(unsigned int opcode)
-{
- switch ((opcode >> 24) & 0xf)
- {
- case 0xc:
- case 0xd:
- if ((opcode >> 20) & 0x1)
- {
- switch ((opcode >> 8) & 0xf)
- {
- case 0x1: return PerformLDF(opcode); break;
- case 0x2: return PerformLFM(opcode); break;
- default: return 0;
- }
- }
- else
- {
- switch ((opcode >> 8) & 0xf)
- {
- case 0x1: return PerformSTF(opcode); break;
- case 0x2: return PerformSFM(opcode); break;
- default: return 0;
- }
- }
- break;
-
- case 0xe:
- if (opcode & 0x10)
- return EmulateCPDO(opcode);
- else
- return EmulateCPRT(opcode);
- break;
-
- default: return 0;
- }
-}
-#endif
diff --git a/linux-user/arm/nwfpe/fpa11_cpdo.c b/linux-user/arm/nwfpe/fpa11_cpdo.c
deleted file mode 100644
index 94ac98aef5..0000000000
--- a/linux-user/arm/nwfpe/fpa11_cpdo.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.COM, 1998,1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "fpa11.h"
-#include "fpopcode.h"
-
-unsigned int EmulateCPDO(const unsigned int opcode)
-{
- FPA11 *fpa11 = GET_FPA11();
- unsigned int Fd, nType, nDest, nRc = 1;
-
- //printk("EmulateCPDO(0x%08x)\n",opcode);
-
- /* Get the destination size. If not valid let Linux perform
- an invalid instruction trap. */
- nDest = getDestinationSize(opcode);
- if (typeNone == nDest) return 0;
-
- SetRoundingMode(opcode);
-
- /* Compare the size of the operands in Fn and Fm.
- Choose the largest size and perform operations in that size,
- in order to make use of all the precision of the operands.
- If Fm is a constant, we just grab a constant of a size
- matching the size of the operand in Fn. */
- if (MONADIC_INSTRUCTION(opcode))
- nType = nDest;
- else
- nType = fpa11->fType[getFn(opcode)];
-
- if (!CONSTANT_FM(opcode))
- {
- register unsigned int Fm = getFm(opcode);
- if (nType < fpa11->fType[Fm])
- {
- nType = fpa11->fType[Fm];
- }
- }
-
- switch (nType)
- {
- case typeSingle : nRc = SingleCPDO(opcode); break;
- case typeDouble : nRc = DoubleCPDO(opcode); break;
- case typeExtended : nRc = ExtendedCPDO(opcode); break;
- default : nRc = 0;
- }
-
- /* If the operation succeeded, check to see if the result in the
- destination register is the correct size. If not force it
- to be. */
- Fd = getFd(opcode);
- nType = fpa11->fType[Fd];
- if ((0 != nRc) && (nDest != nType))
- {
- switch (nDest)
- {
- case typeSingle:
- {
- if (typeDouble == nType)
- fpa11->fpreg[Fd].fSingle =
- float64_to_float32(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status);
- else
- fpa11->fpreg[Fd].fSingle =
- floatx80_to_float32(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
- }
- break;
-
- case typeDouble:
- {
- if (typeSingle == nType)
- fpa11->fpreg[Fd].fDouble =
- float32_to_float64(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status);
- else
- fpa11->fpreg[Fd].fDouble =
- floatx80_to_float64(fpa11->fpreg[Fd].fExtended, &fpa11->fp_status);
- }
- break;
-
- case typeExtended:
- {
- if (typeSingle == nType)
- fpa11->fpreg[Fd].fExtended =
- float32_to_floatx80(fpa11->fpreg[Fd].fSingle, &fpa11->fp_status);
- else
- fpa11->fpreg[Fd].fExtended =
- float64_to_floatx80(fpa11->fpreg[Fd].fDouble, &fpa11->fp_status);
- }
- break;
- }
-
- fpa11->fType[Fd] = nDest;
- }
-
- return nRc;
-}
diff --git a/linux-user/arm/nwfpe/fpa11_cpdt.c b/linux-user/arm/nwfpe/fpa11_cpdt.c
deleted file mode 100644
index fee525937c..0000000000
--- a/linux-user/arm/nwfpe/fpa11_cpdt.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.com, 1998-1999
- (c) Philip Blundell, 1998
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "fpa11.h"
-#include "fpu/softfloat.h"
-#include "fpopcode.h"
-//#include "fpmodule.h"
-//#include "fpmodule.inl"
-
-//#include <asm/uaccess.h>
-
-static inline
-void loadSingle(const unsigned int Fn, target_ulong addr)
-{
- FPA11 *fpa11 = GET_FPA11();
- fpa11->fType[Fn] = typeSingle;
- /* FIXME - handle failure of get_user() */
- get_user_u32(float32_val(fpa11->fpreg[Fn].fSingle), addr);
-}
-
-static inline
-void loadDouble(const unsigned int Fn, target_ulong addr)
-{
- FPA11 *fpa11 = GET_FPA11();
- unsigned int *p;
- p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
- fpa11->fType[Fn] = typeDouble;
-#if HOST_BIG_ENDIAN
- /* FIXME - handle failure of get_user() */
- get_user_u32(p[0], addr); /* sign & exponent */
- get_user_u32(p[1], addr + 4);
-#else
- /* FIXME - handle failure of get_user() */
- get_user_u32(p[0], addr + 4);
- get_user_u32(p[1], addr); /* sign & exponent */
-#endif
-}
-
-static inline
-void loadExtended(const unsigned int Fn, target_ulong addr)
-{
- FPA11 *fpa11 = GET_FPA11();
- unsigned int *p;
- p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
- fpa11->fType[Fn] = typeExtended;
- /* FIXME - handle failure of get_user() */
- get_user_u32(p[0], addr); /* sign & exponent */
- get_user_u32(p[1], addr + 8); /* ls bits */
- get_user_u32(p[2], addr + 4); /* ms bits */
-}
-
-static inline
-void loadMultiple(const unsigned int Fn, target_ulong addr)
-{
- FPA11 *fpa11 = GET_FPA11();
- register unsigned int *p;
- unsigned long x;
-
- p = (unsigned int*)&(fpa11->fpreg[Fn]);
- /* FIXME - handle failure of get_user() */
- get_user_u32(x, addr);
- fpa11->fType[Fn] = (x >> 14) & 0x00000003;
-
- switch (fpa11->fType[Fn])
- {
- case typeSingle:
- case typeDouble:
- {
- /* FIXME - handle failure of get_user() */
- get_user_u32(p[0], addr + 8); /* Single */
- get_user_u32(p[1], addr + 4); /* double msw */
- p[2] = 0; /* empty */
- }
- break;
-
- case typeExtended:
- {
- /* FIXME - handle failure of get_user() */
- get_user_u32(p[1], addr + 8);
- get_user_u32(p[2], addr + 4); /* msw */
- p[0] = (x & 0x80003fff);
- }
- break;
- }
-}
-
-static inline
-void storeSingle(const unsigned int Fn, target_ulong addr)
-{
- FPA11 *fpa11 = GET_FPA11();
- float32 val;
- register unsigned int *p = (unsigned int*)&val;
-
- switch (fpa11->fType[Fn])
- {
- case typeDouble:
- val = float64_to_float32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
- break;
-
- case typeExtended:
- val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status);
- break;
-
- default: val = fpa11->fpreg[Fn].fSingle;
- }
-
- /* FIXME - handle put_user() failures */
- put_user_u32(p[0], addr);
-}
-
-static inline
-void storeDouble(const unsigned int Fn, target_ulong addr)
-{
- FPA11 *fpa11 = GET_FPA11();
- float64 val;
- register unsigned int *p = (unsigned int*)&val;
-
- switch (fpa11->fType[Fn])
- {
- case typeSingle:
- val = float32_to_float64(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
- break;
-
- case typeExtended:
- val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status);
- break;
-
- default: val = fpa11->fpreg[Fn].fDouble;
- }
- /* FIXME - handle put_user() failures */
-#if HOST_BIG_ENDIAN
- put_user_u32(p[0], addr); /* msw */
- put_user_u32(p[1], addr + 4); /* lsw */
-#else
- put_user_u32(p[1], addr); /* msw */
- put_user_u32(p[0], addr + 4); /* lsw */
-#endif
-}
-
-static inline
-void storeExtended(const unsigned int Fn, target_ulong addr)
-{
- FPA11 *fpa11 = GET_FPA11();
- floatx80 val;
- register unsigned int *p = (unsigned int*)&val;
-
- switch (fpa11->fType[Fn])
- {
- case typeSingle:
- val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
- break;
-
- case typeDouble:
- val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
- break;
-
- default: val = fpa11->fpreg[Fn].fExtended;
- }
-
- /* FIXME - handle put_user() failures */
- put_user_u32(p[0], addr); /* sign & exp */
- put_user_u32(p[1], addr + 8);
- put_user_u32(p[2], addr + 4); /* msw */
-}
-
-static inline
-void storeMultiple(const unsigned int Fn, target_ulong addr)
-{
- FPA11 *fpa11 = GET_FPA11();
- register unsigned int nType, *p;
-
- p = (unsigned int*)&(fpa11->fpreg[Fn]);
- nType = fpa11->fType[Fn];
-
- switch (nType)
- {
- case typeSingle:
- case typeDouble:
- {
- put_user_u32(p[0], addr + 8); /* single */
- put_user_u32(p[1], addr + 4); /* double msw */
- put_user_u32(nType << 14, addr);
- }
- break;
-
- case typeExtended:
- {
- put_user_u32(p[2], addr + 4); /* msw */
- put_user_u32(p[1], addr + 8);
- put_user_u32((p[0] & 0x80003fff) | (nType << 14), addr);
- }
- break;
- }
-}
-
-static unsigned int PerformLDF(const unsigned int opcode)
-{
- target_ulong pBase, pAddress, pFinal;
- unsigned int nRc = 1,
- write_back = WRITE_BACK(opcode);
-
- //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
-
- pBase = readRegister(getRn(opcode));
- if (ARM_REG_PC == getRn(opcode))
- {
- pBase += 8;
- write_back = 0;
- }
-
- pFinal = pBase;
- if (BIT_UP_SET(opcode))
- pFinal += getOffset(opcode) * 4;
- else
- pFinal -= getOffset(opcode) * 4;
-
- if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
- switch (opcode & MASK_TRANSFER_LENGTH)
- {
- case TRANSFER_SINGLE : loadSingle(getFd(opcode),pAddress); break;
- case TRANSFER_DOUBLE : loadDouble(getFd(opcode),pAddress); break;
- case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break;
- default: nRc = 0;
- }
-
- if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
- return nRc;
-}
-
-static unsigned int PerformSTF(const unsigned int opcode)
-{
- target_ulong pBase, pAddress, pFinal;
- unsigned int nRc = 1,
- write_back = WRITE_BACK(opcode);
-
- //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
- SetRoundingMode(ROUND_TO_NEAREST);
-
- pBase = readRegister(getRn(opcode));
- if (ARM_REG_PC == getRn(opcode))
- {
- pBase += 8;
- write_back = 0;
- }
-
- pFinal = pBase;
- if (BIT_UP_SET(opcode))
- pFinal += getOffset(opcode) * 4;
- else
- pFinal -= getOffset(opcode) * 4;
-
- if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
- switch (opcode & MASK_TRANSFER_LENGTH)
- {
- case TRANSFER_SINGLE : storeSingle(getFd(opcode),pAddress); break;
- case TRANSFER_DOUBLE : storeDouble(getFd(opcode),pAddress); break;
- case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break;
- default: nRc = 0;
- }
-
- if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
- return nRc;
-}
-
-static unsigned int PerformLFM(const unsigned int opcode)
-{
- unsigned int i, Fd,
- write_back = WRITE_BACK(opcode);
- target_ulong pBase, pAddress, pFinal;
-
- pBase = readRegister(getRn(opcode));
- if (ARM_REG_PC == getRn(opcode))
- {
- pBase += 8;
- write_back = 0;
- }
-
- pFinal = pBase;
- if (BIT_UP_SET(opcode))
- pFinal += getOffset(opcode) * 4;
- else
- pFinal -= getOffset(opcode) * 4;
-
- if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
- Fd = getFd(opcode);
- for (i=getRegisterCount(opcode);i>0;i--)
- {
- loadMultiple(Fd,pAddress);
- pAddress += 12; Fd++;
- if (Fd == 8) Fd = 0;
- }
-
- if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
- return 1;
-}
-
-static unsigned int PerformSFM(const unsigned int opcode)
-{
- unsigned int i, Fd,
- write_back = WRITE_BACK(opcode);
- target_ulong pBase, pAddress, pFinal;
-
- pBase = readRegister(getRn(opcode));
- if (ARM_REG_PC == getRn(opcode))
- {
- pBase += 8;
- write_back = 0;
- }
-
- pFinal = pBase;
- if (BIT_UP_SET(opcode))
- pFinal += getOffset(opcode) * 4;
- else
- pFinal -= getOffset(opcode) * 4;
-
- if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
- Fd = getFd(opcode);
- for (i=getRegisterCount(opcode);i>0;i--)
- {
- storeMultiple(Fd,pAddress);
- pAddress += 12; Fd++;
- if (Fd == 8) Fd = 0;
- }
-
- if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
- return 1;
-}
-
-#if 1
-unsigned int EmulateCPDT(const unsigned int opcode)
-{
- unsigned int nRc = 0;
-
- //printk("EmulateCPDT(0x%08x)\n",opcode);
-
- if (LDF_OP(opcode))
- {
- nRc = PerformLDF(opcode);
- }
- else if (LFM_OP(opcode))
- {
- nRc = PerformLFM(opcode);
- }
- else if (STF_OP(opcode))
- {
- nRc = PerformSTF(opcode);
- }
- else if (SFM_OP(opcode))
- {
- nRc = PerformSFM(opcode);
- }
- else
- {
- nRc = 0;
- }
-
- return nRc;
-}
-#endif
diff --git a/linux-user/arm/nwfpe/fpa11_cprt.c b/linux-user/arm/nwfpe/fpa11_cprt.c
deleted file mode 100644
index 04dc2ebb02..0000000000
--- a/linux-user/arm/nwfpe/fpa11_cprt.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.COM, 1998,1999
- (c) Philip Blundell, 1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "fpa11.h"
-#include "fpu/softfloat.h"
-#include "fpopcode.h"
-#include "fpa11.inl"
-//#include "fpmodule.h"
-//#include "fpmodule.inl"
-
-unsigned int PerformFLT(const unsigned int opcode);
-unsigned int PerformFIX(const unsigned int opcode);
-
-static unsigned int
-PerformComparison(const unsigned int opcode);
-
-unsigned int EmulateCPRT(const unsigned int opcode)
-{
- unsigned int nRc = 1;
-
- //printk("EmulateCPRT(0x%08x)\n",opcode);
-
- if (opcode & 0x800000)
- {
- /* This is some variant of a comparison (PerformComparison will
- sort out which one). Since most of the other CPRT
- instructions are oddball cases of some sort or other it makes
- sense to pull this out into a fast path. */
- return PerformComparison(opcode);
- }
-
- /* Hint to GCC that we'd like a jump table rather than a load of CMPs */
- switch ((opcode & 0x700000) >> 20)
- {
- case FLT_CODE >> 20: nRc = PerformFLT(opcode); break;
- case FIX_CODE >> 20: nRc = PerformFIX(opcode); break;
-
- case WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break;
- case RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break;
-
-#if 0 /* We currently have no use for the FPCR, so there's no point
- in emulating it. */
- case WFC_CODE >> 20: writeFPCR(readRegister(getRd(opcode)));
- case RFC_CODE >> 20: writeRegister(getRd(opcode),readFPCR()); break;
-#endif
-
- default: nRc = 0;
- }
-
- return nRc;
-}
-
-unsigned int PerformFLT(const unsigned int opcode)
-{
- FPA11 *fpa11 = GET_FPA11();
-
- unsigned int nRc = 1;
- SetRoundingMode(opcode);
-
- switch (opcode & MASK_ROUNDING_PRECISION)
- {
- case ROUND_SINGLE:
- {
- fpa11->fType[getFn(opcode)] = typeSingle;
- fpa11->fpreg[getFn(opcode)].fSingle =
- int32_to_float32(readRegister(getRd(opcode)), &fpa11->fp_status);
- }
- break;
-
- case ROUND_DOUBLE:
- {
- fpa11->fType[getFn(opcode)] = typeDouble;
- fpa11->fpreg[getFn(opcode)].fDouble =
- int32_to_float64(readRegister(getRd(opcode)), &fpa11->fp_status);
- }
- break;
-
- case ROUND_EXTENDED:
- {
- fpa11->fType[getFn(opcode)] = typeExtended;
- fpa11->fpreg[getFn(opcode)].fExtended =
- int32_to_floatx80(readRegister(getRd(opcode)), &fpa11->fp_status);
- }
- break;
-
- default: nRc = 0;
- }
-
- return nRc;
-}
-
-unsigned int PerformFIX(const unsigned int opcode)
-{
- FPA11 *fpa11 = GET_FPA11();
- unsigned int nRc = 1;
- unsigned int Fn = getFm(opcode);
-
- SetRoundingMode(opcode);
-
- switch (fpa11->fType[Fn])
- {
- case typeSingle:
- {
- writeRegister(getRd(opcode),
- float32_to_int32(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status));
- }
- break;
-
- case typeDouble:
- {
- //printf("F%d is 0x%" PRIx64 "\n",Fn,fpa11->fpreg[Fn].fDouble);
- writeRegister(getRd(opcode),
- float64_to_int32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status));
- }
- break;
-
- case typeExtended:
- {
- writeRegister(getRd(opcode),
- floatx80_to_int32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status));
- }
- break;
-
- default: nRc = 0;
- }
-
- return nRc;
-}
-
-
-static __inline unsigned int
-PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
-{
- FPA11 *fpa11 = GET_FPA11();
- unsigned int flags = 0;
-
- /* test for less than condition */
- if (floatx80_lt(Fn,Fm, &fpa11->fp_status))
- {
- flags |= CC_NEGATIVE;
- }
-
- /* test for equal condition */
- if (floatx80_eq_quiet(Fn,Fm, &fpa11->fp_status))
- {
- flags |= CC_ZERO;
- }
-
- /* test for greater than or equal condition */
- if (floatx80_lt(Fm,Fn, &fpa11->fp_status))
- {
- flags |= CC_CARRY;
- }
-
- writeConditionCodes(flags);
- return 1;
-}
-
-/* This instruction sets the flags N, Z, C, V in the FPSR. */
-
-static unsigned int PerformComparison(const unsigned int opcode)
-{
- FPA11 *fpa11 = GET_FPA11();
- unsigned int Fn, Fm;
- floatx80 rFn, rFm;
- int e_flag = opcode & 0x400000; /* 1 if CxFE */
- int n_flag = opcode & 0x200000; /* 1 if CNxx */
- unsigned int flags = 0;
-
- //printk("PerformComparison(0x%08x)\n",opcode);
-
- Fn = getFn(opcode);
- Fm = getFm(opcode);
-
- /* Check for unordered condition and convert all operands to 80-bit
- format.
- ?? Might be some mileage in avoiding this conversion if possible.
- Eg, if both operands are 32-bit, detect this and do a 32-bit
- comparison (cheaper than an 80-bit one). */
- switch (fpa11->fType[Fn])
- {
- case typeSingle:
- //printk("single.\n");
- if (float32_is_any_nan(fpa11->fpreg[Fn].fSingle))
- goto unordered;
- rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status);
- break;
-
- case typeDouble:
- //printk("double.\n");
- if (float64_is_any_nan(fpa11->fpreg[Fn].fDouble))
- goto unordered;
- rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status);
- break;
-
- case typeExtended:
- //printk("extended.\n");
- if (floatx80_is_any_nan(fpa11->fpreg[Fn].fExtended))
- goto unordered;
- rFn = fpa11->fpreg[Fn].fExtended;
- break;
-
- default: return 0;
- }
-
- if (CONSTANT_FM(opcode))
- {
- //printk("Fm is a constant: #%d.\n",Fm);
- rFm = getExtendedConstant(Fm);
- if (floatx80_is_any_nan(rFm))
- goto unordered;
- }
- else
- {
- //printk("Fm = r%d which contains a ",Fm);
- switch (fpa11->fType[Fm])
- {
- case typeSingle:
- //printk("single.\n");
- if (float32_is_any_nan(fpa11->fpreg[Fm].fSingle))
- goto unordered;
- rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status);
- break;
-
- case typeDouble:
- //printk("double.\n");
- if (float64_is_any_nan(fpa11->fpreg[Fm].fDouble))
- goto unordered;
- rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status);
- break;
-
- case typeExtended:
- //printk("extended.\n");
- if (floatx80_is_any_nan(fpa11->fpreg[Fm].fExtended))
- goto unordered;
- rFm = fpa11->fpreg[Fm].fExtended;
- break;
-
- default: return 0;
- }
- }
-
- if (n_flag)
- {
- rFm.high ^= 0x8000;
- }
-
- return PerformComparisonOperation(rFn,rFm);
-
- unordered:
- /* ?? The FPA data sheet is pretty vague about this, in particular
- about whether the non-E comparisons can ever raise exceptions.
- This implementation is based on a combination of what it says in
- the data sheet, observation of how the Acorn emulator actually
- behaves (and how programs expect it to) and guesswork. */
- flags |= CC_OVERFLOW;
- flags &= ~(CC_ZERO | CC_NEGATIVE);
-
- if (BIT_AC & readFPSR()) flags |= CC_CARRY;
-
- if (e_flag) float_raise(float_flag_invalid, &fpa11->fp_status);
-
- writeConditionCodes(flags);
- return 1;
-}
diff --git a/linux-user/arm/nwfpe/fpopcode.c b/linux-user/arm/nwfpe/fpopcode.c
deleted file mode 100644
index 6784256d28..0000000000
--- a/linux-user/arm/nwfpe/fpopcode.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.COM, 1998,1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "fpa11.h"
-#include "fpu/softfloat.h"
-#include "fpopcode.h"
-#include "fpsr.h"
-//#include "fpmodule.h"
-//#include "fpmodule.inl"
-
-const floatx80 floatx80Constant[] = {
- { 0x0000000000000000ULL, 0x0000}, /* extended 0.0 */
- { 0x8000000000000000ULL, 0x3fff}, /* extended 1.0 */
- { 0x8000000000000000ULL, 0x4000}, /* extended 2.0 */
- { 0xc000000000000000ULL, 0x4000}, /* extended 3.0 */
- { 0x8000000000000000ULL, 0x4001}, /* extended 4.0 */
- { 0xa000000000000000ULL, 0x4001}, /* extended 5.0 */
- { 0x8000000000000000ULL, 0x3ffe}, /* extended 0.5 */
- { 0xa000000000000000ULL, 0x4002} /* extended 10.0 */
-};
-
-const float64 float64Constant[] = {
- const_float64(0x0000000000000000ULL), /* double 0.0 */
- const_float64(0x3ff0000000000000ULL), /* double 1.0 */
- const_float64(0x4000000000000000ULL), /* double 2.0 */
- const_float64(0x4008000000000000ULL), /* double 3.0 */
- const_float64(0x4010000000000000ULL), /* double 4.0 */
- const_float64(0x4014000000000000ULL), /* double 5.0 */
- const_float64(0x3fe0000000000000ULL), /* double 0.5 */
- const_float64(0x4024000000000000ULL) /* double 10.0 */
-};
-
-const float32 float32Constant[] = {
- const_float32(0x00000000), /* single 0.0 */
- const_float32(0x3f800000), /* single 1.0 */
- const_float32(0x40000000), /* single 2.0 */
- const_float32(0x40400000), /* single 3.0 */
- const_float32(0x40800000), /* single 4.0 */
- const_float32(0x40a00000), /* single 5.0 */
- const_float32(0x3f000000), /* single 0.5 */
- const_float32(0x41200000) /* single 10.0 */
-};
-
-unsigned int getRegisterCount(const unsigned int opcode)
-{
- unsigned int nRc;
-
- switch (opcode & MASK_REGISTER_COUNT)
- {
- case 0x00000000: nRc = 4; break;
- case 0x00008000: nRc = 1; break;
- case 0x00400000: nRc = 2; break;
- case 0x00408000: nRc = 3; break;
- default: nRc = 0;
- }
-
- return(nRc);
-}
-
-unsigned int getDestinationSize(const unsigned int opcode)
-{
- unsigned int nRc;
-
- switch (opcode & MASK_DESTINATION_SIZE)
- {
- case 0x00000000: nRc = typeSingle; break;
- case 0x00000080: nRc = typeDouble; break;
- case 0x00080000: nRc = typeExtended; break;
- default: nRc = typeNone;
- }
-
- return(nRc);
-}
diff --git a/linux-user/arm/nwfpe/single_cpdo.c b/linux-user/arm/nwfpe/single_cpdo.c
deleted file mode 100644
index 21e177baeb..0000000000
--- a/linux-user/arm/nwfpe/single_cpdo.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.COM, 1998,1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "qemu/osdep.h"
-#include "fpa11.h"
-#include "fpu/softfloat.h"
-#include "fpopcode.h"
-
-float32 float32_exp(float32 Fm);
-float32 float32_ln(float32 Fm);
-float32 float32_sin(float32 rFm);
-float32 float32_cos(float32 rFm);
-float32 float32_arcsin(float32 rFm);
-float32 float32_arctan(float32 rFm);
-float32 float32_log(float32 rFm);
-float32 float32_tan(float32 rFm);
-float32 float32_arccos(float32 rFm);
-float32 float32_pow(float32 rFn,float32 rFm);
-float32 float32_pol(float32 rFn,float32 rFm);
-
-unsigned int SingleCPDO(const unsigned int opcode)
-{
- FPA11 *fpa11 = GET_FPA11();
- float32 rFm, rFn = float32_zero;
- unsigned int Fd, Fm, Fn, nRc = 1;
-
- Fm = getFm(opcode);
- if (CONSTANT_FM(opcode))
- {
- rFm = getSingleConstant(Fm);
- }
- else
- {
- switch (fpa11->fType[Fm])
- {
- case typeSingle:
- rFm = fpa11->fpreg[Fm].fSingle;
- break;
-
- default: return 0;
- }
- }
-
- if (!MONADIC_INSTRUCTION(opcode))
- {
- Fn = getFn(opcode);
- switch (fpa11->fType[Fn])
- {
- case typeSingle:
- rFn = fpa11->fpreg[Fn].fSingle;
- break;
-
- default: return 0;
- }
- }
-
- Fd = getFd(opcode);
- switch (opcode & MASK_ARITHMETIC_OPCODE)
- {
- /* dyadic opcodes */
- case ADF_CODE:
- fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm, &fpa11->fp_status);
- break;
-
- case MUF_CODE:
- case FML_CODE:
- fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm, &fpa11->fp_status);
- break;
-
- case SUF_CODE:
- fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm, &fpa11->fp_status);
- break;
-
- case RSF_CODE:
- fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn, &fpa11->fp_status);
- break;
-
- case DVF_CODE:
- case FDV_CODE:
- fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm, &fpa11->fp_status);
- break;
-
- case RDF_CODE:
- case FRD_CODE:
- fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn, &fpa11->fp_status);
- break;
-
-#if 0
- case POW_CODE:
- fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm);
- break;
-
- case RPW_CODE:
- fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn);
- break;
-#endif
-
- case RMF_CODE:
- fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm, &fpa11->fp_status);
- break;
-
-#if 0
- case POL_CODE:
- fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm);
- break;
-#endif
-
- /* monadic opcodes */
- case MVF_CODE:
- fpa11->fpreg[Fd].fSingle = rFm;
- break;
-
- case MNF_CODE:
- fpa11->fpreg[Fd].fSingle = float32_chs(rFm);
- break;
-
- case ABS_CODE:
- fpa11->fpreg[Fd].fSingle = float32_abs(rFm);
- break;
-
- case RND_CODE:
- case URD_CODE:
- fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm, &fpa11->fp_status);
- break;
-
- case SQT_CODE:
- fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm, &fpa11->fp_status);
- break;
-
-#if 0
- case LOG_CODE:
- fpa11->fpreg[Fd].fSingle = float32_log(rFm);
- break;
-
- case LGN_CODE:
- fpa11->fpreg[Fd].fSingle = float32_ln(rFm);
- break;
-
- case EXP_CODE:
- fpa11->fpreg[Fd].fSingle = float32_exp(rFm);
- break;
-
- case SIN_CODE:
- fpa11->fpreg[Fd].fSingle = float32_sin(rFm);
- break;
-
- case COS_CODE:
- fpa11->fpreg[Fd].fSingle = float32_cos(rFm);
- break;
-
- case TAN_CODE:
- fpa11->fpreg[Fd].fSingle = float32_tan(rFm);
- break;
-
- case ASN_CODE:
- fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm);
- break;
-
- case ACS_CODE:
- fpa11->fpreg[Fd].fSingle = float32_arccos(rFm);
- break;
-
- case ATN_CODE:
- fpa11->fpreg[Fd].fSingle = float32_arctan(rFm);
- break;
-#endif
-
- case NRM_CODE:
- break;
-
- default:
- {
- nRc = 0;
- }
- }
-
- if (0 != nRc) fpa11->fType[Fd] = typeSingle;
- return nRc;
-}
-
-#if 0
-float32 float32_exp(float32 Fm)
-{
-//series
-}
-
-float32 float32_ln(float32 Fm)
-{
-//series
-}
-
-float32 float32_sin(float32 rFm)
-{
-//series
-}
-
-float32 float32_cos(float32 rFm)
-{
-//series
-}
-
-float32 float32_arcsin(float32 rFm)
-{
-//series
-}
-
-float32 float32_arctan(float32 rFm)
-{
- //series
-}
-
-float32 float32_arccos(float32 rFm)
-{
- //return float32_sub(halfPi,float32_arcsin(rFm));
-}
-
-float32 float32_log(float32 rFm)
-{
- return float32_div(float32_ln(rFm),getSingleConstant(7));
-}
-
-float32 float32_tan(float32 rFm)
-{
- return float32_div(float32_sin(rFm),float32_cos(rFm));
-}
-
-float32 float32_pow(float32 rFn,float32 rFm)
-{
- return float32_exp(float32_mul(rFm,float32_ln(rFn)));
-}
-
-float32 float32_pol(float32 rFn,float32 rFm)
-{
- return float32_arctan(float32_div(rFn,rFm));
-}
-#endif
diff --git a/linux-user/arm/meson.build b/linux-user/arm/meson.build
index 348ffb810d..4f35536c13 100644
--- a/linux-user/arm/meson.build
+++ b/linux-user/arm/meson.build
@@ -1,5 +1,3 @@
-subdir('nwfpe')
-
syscall_nr_generators += {
'arm': generator(sh,
arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ],
diff --git a/linux-user/arm/nwfpe/fpa11.inl b/linux-user/arm/nwfpe/fpa11.inl
deleted file mode 100644
index 6c6f380d4d..0000000000
--- a/linux-user/arm/nwfpe/fpa11.inl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- NetWinder Floating Point Emulator
- (c) Rebel.COM, 1998,1999
-
- Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "fpa11.h"
-
-/* Read and write floating point status register */
-static inline unsigned int readFPSR(void)
-{
- FPA11 *fpa11 = GET_FPA11();
- return(fpa11->fpsr);
-}
-
-static inline void writeFPSR(FPSR reg)
-{
- FPA11 *fpa11 = GET_FPA11();
- /* the sysid byte in the status register is readonly */
- fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID);
-}
-
-/* Read and write floating point control register */
-static inline FPCR readFPCR(void)
-{
- FPA11 *fpa11 = GET_FPA11();
- /* clear SB, AB and DA bits before returning FPCR */
- return(fpa11->fpcr & ~MASK_RFC);
-}
-
-static inline void writeFPCR(FPCR reg)
-{
- FPA11 *fpa11 = GET_FPA11();
- fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */
- fpa11->fpcr |= (reg & MASK_WFC); /* write SB, AB and DA bits */
-}
diff --git a/linux-user/arm/nwfpe/meson.build b/linux-user/arm/nwfpe/meson.build
deleted file mode 100644
index 1c27e55f2a..0000000000
--- a/linux-user/arm/nwfpe/meson.build
+++ /dev/null
@@ -1,10 +0,0 @@
-linux_user_ss.add(when: 'TARGET_ARM', if_true: files(
- 'double_cpdo.c',
- 'extended_cpdo.c',
- 'fpa11.c',
- 'fpa11_cpdo.c',
- 'fpa11_cpdt.c',
- 'fpa11_cprt.c',
- 'fpopcode.c',
- 'single_cpdo.c',
-))
--
2.43.0
On Mon, 13 Apr 2026 at 08:33, Richard Henderson <richard.henderson@linaro.org> wrote: > > This emulation is present in the linux kernel only for > a very restricted set of configurations: > > config FPE_NWFPE > bool "NWFPE math emulation" > depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL > > EABI is the default for all armv6 capable kernels, so this > isn't enabled in practice for some time. > > GCC removed support for the FPA11 somewhere before gcc-5. > > The code within nwfpe is not thread-safe, using several > global variables. I agree that this is probably something we should drop, but I think it needs to go through the deprecate-and-drop cycle first. We probably just have time to mark it deprecated for 11.0 if we're quick about the patch and we have something else that needs to go into rc4. thanks -- PMM
© 2016 - 2026 Red Hat, Inc.