diff --git a/gdb/NEWS b/gdb/NEWS
index 555ef2ddf77..fcd7b686e02 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,10 @@
 
 *** Changes since GDB 12
 
+* Removed support for the 32-bit Arm FPA floating point format.  FPA is an
+  old floating point format that is no longer supported in GCC since at least
+  2012.
+
 * GDB now supports dumping memory tag data for AArch64 MTE.  It also supports
   reading memory tag data for AArch64 MTE from core files generated by
   the gcore command or the Linux kernel.
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index eda79ec6d35..4d36cd47567 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -551,7 +551,7 @@ aarch32_fetch_registers (struct regcache *regcache, int regno)
       if (tdep->vfp_register_count > 0)
 	fetch_fpregs_from_thread (regcache);
     }
-  else if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
+  else if (regno <= ARM_PC_REGNUM || regno == ARM_PS_REGNUM)
     fetch_gregs_from_thread (regcache);
   else if (tdep->vfp_register_count > 0
 	   && regno >= ARM_D0_REGNUM
@@ -627,7 +627,7 @@ aarch32_store_registers (struct regcache *regcache, int regno)
       if (tdep->vfp_register_count > 0)
 	store_fpregs_to_thread (regcache);
     }
-  else if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
+  else if (regno <= ARM_PC_REGNUM || regno == ARM_PS_REGNUM)
     store_gregs_to_thread (regcache);
   else if (tdep->vfp_register_count > 0
 	   && regno >= ARM_D0_REGNUM
diff --git a/gdb/arch/arm.c b/gdb/arch/arm.c
index 14f0a7a7f6c..9771a60f30f 100644
--- a/gdb/arch/arm.c
+++ b/gdb/arch/arm.c
@@ -27,7 +27,6 @@
 #include "../features/arm/arm-vfpv3.c"
 #include "../features/arm/xscale-iwmmxt.c"
 #include "../features/arm/arm-m-profile.c"
-#include "../features/arm/arm-m-profile-with-fpa.c"
 #include "../features/arm/arm-m-profile-mve.c"
 #include "../features/arm/arm-m-system.c"
 
@@ -441,10 +440,6 @@ arm_create_mprofile_target_description (arm_m_profile_type m_type)
       regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum);
       break;
 
-    case ARM_M_TYPE_WITH_FPA:
-      regnum = create_feature_arm_arm_m_profile_with_fpa (tdesc, regnum);
-      break;
-
     case ARM_M_TYPE_MVE:
       regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
       regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum);
diff --git a/gdb/arch/arm.h b/gdb/arch/arm.h
index 36757493406..74a6ba93bc7 100644
--- a/gdb/arch/arm.h
+++ b/gdb/arch/arm.h
@@ -44,11 +44,6 @@ enum gdb_regnum {
   ARM_SP_REGNUM = 13,		/* Contains address of top of stack */
   ARM_LR_REGNUM = 14,		/* address to return to from a function call */
   ARM_PC_REGNUM = 15,		/* Contains program counter */
-  /* F0..F7 are the fp registers for the (obsolete) FPA architecture.  */
-  ARM_F0_REGNUM = 16,		/* first floating point register */
-  ARM_F3_REGNUM = 19,		/* last floating point argument register */
-  ARM_F7_REGNUM = 23, 		/* last floating point register */
-  ARM_FPS_REGNUM = 24,		/* floating point status register */
   ARM_PS_REGNUM = 25,		/* Contains processor status */
   ARM_WR0_REGNUM,		/* WMMX data registers.  */
   ARM_WR15_REGNUM = ARM_WR0_REGNUM + 15,
@@ -67,7 +62,6 @@ enum gdb_regnum {
   ARM_FP_REGNUM = 11,		/* Frame register in ARM code, if used.  */
   THUMB_FP_REGNUM = 7,		/* Frame register in Thumb code, if used.  */
   ARM_LAST_ARG_REGNUM = ARM_A4_REGNUM,
-  ARM_LAST_FP_ARG_REGNUM = ARM_F3_REGNUM
 };
 
 /* Register count constants.  */
@@ -103,7 +97,6 @@ enum arm_fp_type {
 enum arm_m_profile_type {
    ARM_M_TYPE_M_PROFILE,
    ARM_M_TYPE_VFP_D16,
-   ARM_M_TYPE_WITH_FPA,
    ARM_M_TYPE_MVE,
    ARM_M_TYPE_SYSTEM,
    ARM_M_TYPE_INVALID
@@ -157,8 +150,6 @@ enum system_register_address : CORE_ADDR
 
 /* r0-r12,sp,lr,pc,cpsr.  */
 #define ARM_CORE_REGS_SIZE (17 * ARM_INT_REGISTER_SIZE)
-/* f0-f8,fps.  */
-#define ARM_FP_REGS_SIZE (8 * ARM_FP_REGISTER_SIZE + ARM_INT_REGISTER_SIZE)
 /* d0-d15,fpscr.  */
 #define ARM_VFP2_REGS_SIZE (16 * ARM_VFP_REGISTER_SIZE + ARM_INT_REGISTER_SIZE)
 /* d0-d31,fpscr.  */
diff --git a/gdb/arm-bsd-tdep.c b/gdb/arm-bsd-tdep.c
index 13d6e527d58..72421bb26d5 100644
--- a/gdb/arm-bsd-tdep.c
+++ b/gdb/arm-bsd-tdep.c
@@ -29,39 +29,6 @@
 /* Sizeof `struct reg' in <machine/reg.h>.  */
 #define ARMBSD_SIZEOF_GREGS	(17 * 4)
 
-/* Sizeof `struct fpreg' in <machine/reg.h.  */
-#define ARMBSD_SIZEOF_FPREGS	((1 + (8 * 3)) * 4)
-
-static int
-armbsd_fpreg_offset (int regnum)
-{
-  if (regnum == ARM_FPS_REGNUM)
-    return 0;
-
-  return 4 + (regnum - ARM_F0_REGNUM) * 12;
-}
-
-/* Supply register REGNUM from the buffer specified by FPREGS and LEN
-   in the floating-point register set REGSET to register cache
-   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
-
-static void
-armbsd_supply_fpregset (const struct regset *regset,
-			struct regcache *regcache,
-			int regnum, const void *fpregs, size_t len)
-{
-  const gdb_byte *regs = (const gdb_byte *) fpregs;
-  int i;
-
-  gdb_assert (len >= ARMBSD_SIZEOF_FPREGS);
-
-  for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
-    {
-      if (regnum == i || regnum == -1)
-	regcache->raw_supply (i, regs + armbsd_fpreg_offset (i));
-    }
-}
-
 /* Supply register REGNUM from the buffer specified by GREGS and LEN
    in the general-purpose register set REGSET to register cache
    REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */
@@ -84,13 +51,6 @@ armbsd_supply_gregset (const struct regset *regset,
 
   if (regnum == ARM_PS_REGNUM || regnum == -1)
     regcache->raw_supply (i, regs + 16 * 4);
-
-  if (len >= ARMBSD_SIZEOF_GREGS + ARMBSD_SIZEOF_FPREGS)
-    {
-      regs += ARMBSD_SIZEOF_GREGS;
-      len -= ARMBSD_SIZEOF_GREGS;
-      armbsd_supply_fpregset (regset, regcache, regnum, regs, len);
-    }
 }
 
 /* ARM register sets.  */
@@ -103,12 +63,6 @@ static const struct regset armbsd_gregset =
   REGSET_VARIABLE_SIZE
 };
 
-static const struct regset armbsd_fpregset =
-{
-  NULL,
-  armbsd_supply_fpregset
-};
-
 /* Iterate over supported core file register note sections. */
 
 void
@@ -119,6 +73,4 @@ armbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
 {
   cb (".reg", ARMBSD_SIZEOF_GREGS, ARMBSD_SIZEOF_GREGS, &armbsd_gregset, NULL,
       cb_data);
-  cb (".reg2", ARMBSD_SIZEOF_FPREGS, ARMBSD_SIZEOF_FPREGS, &armbsd_fpregset,
-      NULL, cb_data);
 }
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index 0188c78fe7a..a6a5745fdf9 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -109,96 +109,6 @@ class arm_linux_nat_target final : public linux_nat_target
 
 static arm_linux_nat_target the_arm_linux_nat_target;
 
-/* Get the whole floating point state of the process and store it
-   into regcache.  */
-
-static void
-fetch_fpregs (struct regcache *regcache)
-{
-  int ret, regno, tid;
-  gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];
-
-  /* Get the thread id for the ptrace call.  */
-  tid = regcache->ptid ().lwp ();
-
-  /* Read the floating point state.  */
-  if (have_ptrace_getregset == TRIBOOL_TRUE)
-    {
-      struct iovec iov;
-
-      iov.iov_base = &fp;
-      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
-
-      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov);
-    }
-  else
-    ret = ptrace (PT_GETFPREGS, tid, 0, fp);
-
-  if (ret < 0)
-    perror_with_name (_("Unable to fetch the floating point registers"));
-
-  /* Fetch fpsr.  */
-  regcache->raw_supply (ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET);
-
-  /* Fetch the floating point registers.  */
-  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
-    supply_nwfpe_register (regcache, regno, fp);
-}
-
-/* Save the whole floating point state of the process using
-   the contents from regcache.  */
-
-static void
-store_fpregs (const struct regcache *regcache)
-{
-  int ret, regno, tid;
-  gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];
-
-  /* Get the thread id for the ptrace call.  */
-  tid = regcache->ptid ().lwp ();
-
-  /* Read the floating point state.  */
-  if (have_ptrace_getregset == TRIBOOL_TRUE)
-    {
-      elf_fpregset_t fpregs;
-      struct iovec iov;
-
-      iov.iov_base = &fpregs;
-      iov.iov_len = sizeof (fpregs);
-
-      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov);
-    }
-  else
-    ret = ptrace (PT_GETFPREGS, tid, 0, fp);
-
-  if (ret < 0)
-    perror_with_name (_("Unable to fetch the floating point registers"));
-
-  /* Store fpsr.  */
-  if (REG_VALID == regcache->get_register_status (ARM_FPS_REGNUM))
-    regcache->raw_collect (ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET);
-
-  /* Store the floating point registers.  */
-  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
-    if (REG_VALID == regcache->get_register_status (regno))
-      collect_nwfpe_register (regcache, regno, fp);
-
-  if (have_ptrace_getregset == TRIBOOL_TRUE)
-    {
-      struct iovec iov;
-
-      iov.iov_base = &fp;
-      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;
-
-      ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iov);
-    }
-  else
-    ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);
-
-  if (ret < 0)
-    perror_with_name (_("Unable to store floating point registers"));
-}
-
 /* Fetch all general registers of the process and store into
    regcache.  */
 
@@ -422,15 +332,11 @@ arm_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
 	fetch_wmmx_regs (regcache);
       if (tdep->vfp_register_count > 0)
 	fetch_vfp_regs (regcache);
-      if (tdep->have_fpa_registers)
-	fetch_fpregs (regcache);
     }
   else
     {
-      if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
+      if (regno <= ARM_PC_REGNUM || regno == ARM_PS_REGNUM)
 	fetch_regs (regcache);
-      else if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM)
-	fetch_fpregs (regcache);
       else if (tdep->have_wmmx_registers
 	       && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
 	fetch_wmmx_regs (regcache);
@@ -459,15 +365,11 @@ arm_linux_nat_target::store_registers (struct regcache *regcache, int regno)
 	store_wmmx_regs (regcache);
       if (tdep->vfp_register_count > 0)
 	store_vfp_regs (regcache);
-      if (tdep->have_fpa_registers)
-	store_fpregs (regcache);
     }
   else
     {
-      if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
+      if (regno <= ARM_PC_REGNUM || regno == ARM_PS_REGNUM)
 	store_regs (regcache);
-      else if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
-	store_fpregs (regcache);
       else if (tdep->have_wmmx_registers
 	       && regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
 	store_wmmx_regs (regcache);
@@ -499,7 +401,7 @@ void
 fill_fpregset (const struct regcache *regcache,
 	       gdb_fpregset_t *fpregsetp, int regno)
 {
-  arm_linux_collect_nwfpe (NULL, regcache, regno, fpregsetp, 0);
+  /* FPA is no longer supported.  */
 }
 
 /* Fill GDB's register array with the floating-point register values
@@ -508,7 +410,7 @@ fill_fpregset (const struct regcache *regcache,
 void
 supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
 {
-  arm_linux_supply_nwfpe (NULL, regcache, -1, fpregsetp, 0);
+  /* FPA is no longer supported.  */
 }
 
 /* Fetch the thread-local storage pointer for libthread_db.  */
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index 1feb69fe6dd..d5ada33a05c 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -102,10 +102,8 @@ static const gdb_byte arm_linux_thumb2_le_breakpoint[] = { 0xf0, 0xf7, 0x00, 0xa
 
    For glibc, eglibc, and uclibc the following holds:  If the FP model is 
    SoftVFP or VFP (which implies EABI) then the PC is at offset 9 in the 
-   buffer.  This is also true for the SoftFPA model.  However, for the FPA 
-   model the PC is at offset 21 in the buffer.  */
+   buffer.  */
 #define ARM_LINUX_JB_ELEMENT_SIZE	ARM_INT_REGISTER_SIZE
-#define ARM_LINUX_JB_PC_FPA		21
 #define ARM_LINUX_JB_PC_EABI		9
 
 /*
@@ -540,119 +538,6 @@ arm_linux_collect_gregset (const struct regset *regset,
 			   gregs + ARM_INT_REGISTER_SIZE * ARM_PC_REGNUM);
 }
 
-/* Support for register format used by the NWFPE FPA emulator.  */
-
-#define typeNone		0x00
-#define typeSingle		0x01
-#define typeDouble		0x02
-#define typeExtended		0x03
-
-void
-supply_nwfpe_register (struct regcache *regcache, int regno,
-		       const gdb_byte *regs)
-{
-  const gdb_byte *reg_data;
-  gdb_byte reg_tag;
-  gdb_byte buf[ARM_FP_REGISTER_SIZE];
-
-  reg_data = regs + (regno - ARM_F0_REGNUM) * ARM_FP_REGISTER_SIZE;
-  reg_tag = regs[(regno - ARM_F0_REGNUM) + NWFPE_TAGS_OFFSET];
-  memset (buf, 0, ARM_FP_REGISTER_SIZE);
-
-  switch (reg_tag)
-    {
-    case typeSingle:
-      memcpy (buf, reg_data, 4);
-      break;
-    case typeDouble:
-      memcpy (buf, reg_data + 4, 4);
-      memcpy (buf + 4, reg_data, 4);
-      break;
-    case typeExtended:
-      /* We want sign and exponent, then least significant bits,
-	 then most significant.  NWFPE does sign, most, least.  */
-      memcpy (buf, reg_data, 4);
-      memcpy (buf + 4, reg_data + 8, 4);
-      memcpy (buf + 8, reg_data + 4, 4);
-      break;
-    default:
-      break;
-    }
-
-  regcache->raw_supply (regno, buf);
-}
-
-void
-collect_nwfpe_register (const struct regcache *regcache, int regno,
-			gdb_byte *regs)
-{
-  gdb_byte *reg_data;
-  gdb_byte reg_tag;
-  gdb_byte buf[ARM_FP_REGISTER_SIZE];
-
-  regcache->raw_collect (regno, buf);
-
-  /* NOTE drow/2006-06-07: This code uses the tag already in the
-     register buffer.  I've preserved that when moving the code
-     from the native file to the target file.  But this doesn't
-     always make sense.  */
-
-  reg_data = regs + (regno - ARM_F0_REGNUM) * ARM_FP_REGISTER_SIZE;
-  reg_tag = regs[(regno - ARM_F0_REGNUM) + NWFPE_TAGS_OFFSET];
-
-  switch (reg_tag)
-    {
-    case typeSingle:
-      memcpy (reg_data, buf, 4);
-      break;
-    case typeDouble:
-      memcpy (reg_data, buf + 4, 4);
-      memcpy (reg_data + 4, buf, 4);
-      break;
-    case typeExtended:
-      memcpy (reg_data, buf, 4);
-      memcpy (reg_data + 4, buf + 8, 4);
-      memcpy (reg_data + 8, buf + 4, 4);
-      break;
-    default:
-      break;
-    }
-}
-
-void
-arm_linux_supply_nwfpe (const struct regset *regset,
-			struct regcache *regcache,
-			int regnum, const void *regs_buf, size_t len)
-{
-  const gdb_byte *regs = (const gdb_byte *) regs_buf;
-  int regno;
-
-  if (regnum == ARM_FPS_REGNUM || regnum == -1)
-    regcache->raw_supply (ARM_FPS_REGNUM,
-			 regs + NWFPE_FPSR_OFFSET);
-
-  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
-    if (regnum == -1 || regnum == regno)
-      supply_nwfpe_register (regcache, regno, regs);
-}
-
-void
-arm_linux_collect_nwfpe (const struct regset *regset,
-			 const struct regcache *regcache,
-			 int regnum, void *regs_buf, size_t len)
-{
-  gdb_byte *regs = (gdb_byte *) regs_buf;
-  int regno;
-
-  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
-    if (regnum == -1 || regnum == regno)
-      collect_nwfpe_register (regcache, regno, regs);
-
-  if (regnum == ARM_FPS_REGNUM || regnum == -1)
-    regcache->raw_collect (ARM_FPS_REGNUM,
-			   regs + ARM_INT_REGISTER_SIZE * ARM_FPS_REGNUM);
-}
-
 /* Support VFP register format.  */
 
 #define ARM_LINUX_SIZEOF_VFP (32 * 8 + 4)
@@ -694,11 +579,6 @@ static const struct regset arm_linux_gregset =
     NULL, arm_linux_supply_gregset, arm_linux_collect_gregset
   };
 
-static const struct regset arm_linux_fpregset =
-  {
-    NULL, arm_linux_supply_nwfpe, arm_linux_collect_nwfpe
-  };
-
 static const struct regset arm_linux_vfpregset =
   {
     NULL, arm_linux_supply_vfp, arm_linux_collect_vfp
@@ -720,9 +600,6 @@ arm_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
   if (tdep->vfp_register_count > 0)
     cb (".reg-arm-vfp", ARM_LINUX_SIZEOF_VFP, ARM_LINUX_SIZEOF_VFP,
 	&arm_linux_vfpregset, "VFP floating-point", cb_data);
-  else if (tdep->have_fpa_registers)
-    cb (".reg2", ARM_LINUX_SIZEOF_NWFPE, ARM_LINUX_SIZEOF_NWFPE,
-	&arm_linux_fpregset, "FPA floating-point", cb_data);
 }
 
 /* Determine target description from core file.  */
@@ -1744,14 +1621,10 @@ arm_linux_init_abi (struct gdbarch_info info,
   tdep->thumb2_breakpoint_size = sizeof (arm_linux_thumb2_le_breakpoint);
 
   if (tdep->fp_model == ARM_FLOAT_AUTO)
-    tdep->fp_model = ARM_FLOAT_FPA;
+    tdep->fp_model = ARM_FLOAT_SOFT_VFP;
 
   switch (tdep->fp_model)
     {
-    case ARM_FLOAT_FPA:
-      tdep->jb_pc = ARM_LINUX_JB_PC_FPA;
-      break;
-    case ARM_FLOAT_SOFT_FPA:
     case ARM_FLOAT_SOFT_VFP:
     case ARM_FLOAT_VFP:
       tdep->jb_pc = ARM_LINUX_JB_PC_EABI;
diff --git a/gdb/arm-linux-tdep.h b/gdb/arm-linux-tdep.h
index 6ed55acf9b0..cb92c3f6bbe 100644
--- a/gdb/arm-linux-tdep.h
+++ b/gdb/arm-linux-tdep.h
@@ -23,23 +23,6 @@
 struct regset;
 struct regcache;
 
-#define ARM_LINUX_SIZEOF_NWFPE (8 * ARM_FP_REGISTER_SIZE \
-				+ 2 * ARM_INT_REGISTER_SIZE \
-				+ 8 + ARM_INT_REGISTER_SIZE)
-
-/* Support for register format used by the NWFPE FPA emulator.  Each
-   register takes three words, where either the first one, two, or
-   three hold a single, double, or extended precision value (depending
-   on the corresponding tag).  The register set is eight registers,
-   followed by the fpsr and fpcr, followed by eight tag bytes, and a
-   final word flag which indicates whether NWFPE has been
-   initialized.  */
-
-#define NWFPE_FPSR_OFFSET (8 * ARM_FP_REGISTER_SIZE)
-#define NWFPE_FPCR_OFFSET (NWFPE_FPSR_OFFSET + ARM_INT_REGISTER_SIZE)
-#define NWFPE_TAGS_OFFSET (NWFPE_FPCR_OFFSET + ARM_INT_REGISTER_SIZE)
-#define NWFPE_INITFLAG_OFFSET (NWFPE_TAGS_OFFSET + 8)
-
 void arm_linux_supply_gregset (const struct regset *regset,
 			       struct regcache *regcache,
 			       int regnum, const void *gregs_buf, size_t len);
@@ -47,18 +30,6 @@ void arm_linux_collect_gregset (const struct regset *regset,
 				const struct regcache *regcache,
 				int regnum, void *gregs_buf, size_t len);
 
-void supply_nwfpe_register (struct regcache *regcache, int regno,
-			    const gdb_byte *regs);
-void collect_nwfpe_register (const struct regcache *regcache, int regno,
-			     gdb_byte *regs);
-
-void arm_linux_supply_nwfpe (const struct regset *regset,
-			     struct regcache *regcache,
-			     int regnum, const void *regs_buf, size_t len);
-void arm_linux_collect_nwfpe (const struct regset *regset,
-			      const struct regcache *regcache,
-			      int regnum, void *regs_buf, size_t len);
-
 /* ARM GNU/Linux HWCAP values.  These are in defined in
    <asm/elf.h> in current kernels.  */
 #define HWCAP_VFP       64
diff --git a/gdb/arm-netbsd-nat.c b/gdb/arm-netbsd-nat.c
index 251159154c9..d37a1951c21 100644
--- a/gdb/arm-netbsd-nat.c
+++ b/gdb/arm-netbsd-nat.c
@@ -135,7 +135,7 @@ arm_netbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     {
-      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+      if (regno <= ARM_PC_REGNUM || regno >= ARM_PS_REGNUM)
 	fetch_register (regcache, regno);
       else
 	fetch_fp_register (regcache, regno);
@@ -326,7 +326,7 @@ arm_netbsd_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     {
-      if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
+      if (regno <= ARM_PC_REGNUM || regno >= ARM_PS_REGNUM)
 	store_register (regcache, regno);
       else
 	store_fp_register (regcache, regno);
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index ead9bbf46c5..b33a53612a6 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -134,8 +134,6 @@ static struct cmd_list_element *showarmcmdlist = NULL;
 static const char *const fp_model_strings[] =
 {
   "auto",
-  "softfpa",
-  "fpa",
   "softvfp",
   "vfp",
   NULL
@@ -226,9 +224,7 @@ static const char *const arm_register_names[] =
  "r4",  "r5",  "r6",  "r7",	/*  4  5  6  7 */
  "r8",  "r9",  "r10", "r11",	/*  8  9 10 11 */
  "r12", "sp",  "lr",  "pc",	/* 12 13 14 15 */
- "f0",  "f1",  "f2",  "f3",	/* 16 17 18 19 */
- "f4",  "f5",  "f6",  "f7",	/* 20 21 22 23 */
- "fps", "cpsr" };		/* 24 25       */
+ "cpsr" };			/* 25 */
 
 /* Holds the current set of options to be passed to the disassembler.  */
 static char *arm_disassembler_options;
@@ -1877,7 +1873,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
   enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
   int regno;
   CORE_ADDR offset, current_pc;
-  pv_t regs[ARM_FPS_REGNUM];
+  pv_t regs[ARM_PC_REGNUM];
   CORE_ADDR unrecognized_pc = 0;
   arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
 
@@ -1891,7 +1887,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
      and other operations that rely on a knowledge of the stack
      traceback.  */
 
-  for (regno = 0; regno < ARM_FPS_REGNUM; regno++)
+  for (regno = 0; regno < ARM_PC_REGNUM; regno++)
     regs[regno] = pv_register (regno, 0);
   pv_area stack (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch));
 
@@ -1982,51 +1978,6 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
 	  uint32_t imm = arm_expand_immediate(insn & 0xfff);
 	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -imm);
 	}
-      else if ((insn & 0xffff7fff) == 0xed6d0103	/* stfe f?,
-							   [sp, -#c]! */
-	       && tdep->have_fpa_registers)
-	{
-	  if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
-	    break;
-
-	  regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12);
-	  regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
-	  stack.store (regs[ARM_SP_REGNUM], 12, regs[regno]);
-	}
-      else if ((insn & 0xffbf0fff) == 0xec2d0200	/* sfmfd f0, 4,
-							   [sp!] */
-	       && tdep->have_fpa_registers)
-	{
-	  int n_saved_fp_regs;
-	  unsigned int fp_start_reg, fp_bound_reg;
-
-	  if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
-	    break;
-
-	  if ((insn & 0x800) == 0x800)		/* N0 is set */
-	    {
-	      if ((insn & 0x40000) == 0x40000)	/* N1 is set */
-		n_saved_fp_regs = 3;
-	      else
-		n_saved_fp_regs = 1;
-	    }
-	  else
-	    {
-	      if ((insn & 0x40000) == 0x40000)	/* N1 is set */
-		n_saved_fp_regs = 2;
-	      else
-		n_saved_fp_regs = 4;
-	    }
-
-	  fp_start_reg = ARM_F0_REGNUM + ((insn >> 12) & 0x7);
-	  fp_bound_reg = fp_start_reg + n_saved_fp_regs;
-	  for (; fp_start_reg < fp_bound_reg; fp_start_reg++)
-	    {
-	      regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12);
-	      stack.store (regs[ARM_SP_REGNUM], 12,
-			   regs[fp_start_reg++]);
-	    }
-	}
       else if ((insn & 0xff000000) == 0xeb000000 && cache == NULL) /* bl */
 	{
 	  /* Allow some special function calls when skipping the
@@ -2103,7 +2054,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
       cache->framereg = framereg;
       cache->framesize = framesize;
 
-      for (regno = 0; regno < ARM_FPS_REGNUM; regno++)
+      for (regno = 0; regno < ARM_PC_REGNUM; regno++)
 	if (stack.find_reg (gdbarch, regno, &offset))
 	  {
 	    cache->saved_regs[regno].set_addr (offset);
@@ -4666,58 +4617,6 @@ arm_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
   return sp & ~ (CORE_ADDR) 7;
 }
 
-static void
-print_fpu_flags (struct ui_file *file, int flags)
-{
-  if (flags & (1 << 0))
-    gdb_puts ("IVO ", file);
-  if (flags & (1 << 1))
-    gdb_puts ("DVZ ", file);
-  if (flags & (1 << 2))
-    gdb_puts ("OFL ", file);
-  if (flags & (1 << 3))
-    gdb_puts ("UFL ", file);
-  if (flags & (1 << 4))
-    gdb_puts ("INX ", file);
-  gdb_putc ('\n', file);
-}
-
-/* Print interesting information about the floating point processor
-   (if present) or emulator.  */
-static void
-arm_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
-		      struct frame_info *frame, const char *args)
-{
-  unsigned long status = get_frame_register_unsigned (frame, ARM_FPS_REGNUM);
-  int type;
-
-  type = (status >> 24) & 127;
-  if (status & (1 << 31))
-    gdb_printf (file, _("Hardware FPU type %d\n"), type);
-  else
-    gdb_printf (file, _("Software FPU type %d\n"), type);
-  /* i18n: [floating point unit] mask */
-  gdb_puts (_("mask: "), file);
-  print_fpu_flags (file, status >> 16);
-  /* i18n: [floating point unit] flags */
-  gdb_puts (_("flags: "), file);
-  print_fpu_flags (file, status);
-}
-
-/* Construct the ARM extended floating point type.  */
-static struct type *
-arm_ext_type (struct gdbarch *gdbarch)
-{
-  arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
-
-  if (!tdep->arm_ext_type)
-    tdep->arm_ext_type
-      = arch_float_type (gdbarch, -1, "builtin_type_arm_ext",
-			 floatformats_arm_ext);
-
-  return tdep->arm_ext_type;
-}
-
 static struct type *
 arm_neon_double_type (struct gdbarch *gdbarch)
 {
@@ -4902,14 +4801,7 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
 	return t;
     }
 
-  if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
-    {
-      if (!tdep->have_fpa_registers)
-	return builtin_type (gdbarch)->builtin_void;
-
-      return arm_ext_type (gdbarch);
-    }
-  else if (regnum == ARM_SP_REGNUM)
+  if (regnum == ARM_SP_REGNUM)
     return builtin_type (gdbarch)->builtin_data_ptr;
   else if (regnum == ARM_PC_REGNUM)
     return builtin_type (gdbarch)->builtin_func_ptr;
@@ -4931,17 +4823,6 @@ arm_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
   if (reg >= 0 && reg <= 15)
     return reg;
 
-  /* Legacy FPA encoding.  These were once used in a way which
-     overlapped with VFP register numbering, so their use is
-     discouraged, but GDB doesn't support the ARM toolchain
-     which used them for VFP.  */
-  if (reg >= 16 && reg <= 23)
-    return ARM_F0_REGNUM + reg - 16;
-
-  /* New assignments for the FPA registers.  */
-  if (reg >= 96 && reg <= 103)
-    return ARM_F0_REGNUM + reg - 96;
-
   /* WMMX register assignments.  */
   if (reg >= 104 && reg <= 111)
     return ARM_WCGR0_REGNUM + reg - 104;
@@ -5014,14 +4895,6 @@ arm_register_sim_regno (struct gdbarch *gdbarch, int regnum)
     return SIM_ARM_R0_REGNUM + reg;
   reg -= NUM_GREGS;
 
-  if (reg < NUM_FREGS)
-    return SIM_ARM_FP0_REGNUM + reg;
-  reg -= NUM_FREGS;
-
-  if (reg < NUM_SREGS)
-    return SIM_ARM_FPS_REGNUM + reg;
-  reg -= NUM_SREGS;
-
   internal_error (__FILE__, __LINE__, _("Bad REGNUM %d"), regnum);
 }
 
@@ -8686,20 +8559,6 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
     {
       switch (tdep->fp_model)
 	{
-	case ARM_FLOAT_FPA:
-	  {
-	    /* The value is in register F0 in internal format.  We need to
-	       extract the raw value and then convert it to the desired
-	       internal type.  */
-	    bfd_byte tmpbuf[ARM_FP_REGISTER_SIZE];
-
-	    regs->cooked_read (ARM_F0_REGNUM, tmpbuf);
-	    target_float_convert (tmpbuf, arm_ext_type (gdbarch),
-				  valbuf, type);
-	  }
-	  break;
-
-	case ARM_FLOAT_SOFT_FPA:
 	case ARM_FLOAT_SOFT_VFP:
 	  /* ARM_FLOAT_VFP can arise if this is a variadic function so
 	     not using the VFP ABI code.  */
@@ -8896,18 +8755,10 @@ arm_store_return_value (struct type *type, struct regcache *regs,
 
   if (type->code () == TYPE_CODE_FLT)
     {
-      gdb_byte buf[ARM_FP_REGISTER_SIZE];
       arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
 
       switch (tdep->fp_model)
 	{
-	case ARM_FLOAT_FPA:
-
-	  target_float_convert (valbuf, type, buf, arm_ext_type (gdbarch));
-	  regs->cooked_write (ARM_F0_REGNUM, buf);
-	  break;
-
-	case ARM_FLOAT_SOFT_FPA:
 	case ARM_FLOAT_SOFT_VFP:
 	  /* ARM_FLOAT_VFP can arise if this is a variadic function so
 	     not using the VFP ABI code.  */
@@ -9722,71 +9573,6 @@ arm_elf_osabi_sniffer (bfd *abfd)
   return osabi;
 }
 
-static int
-arm_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
-			 const struct reggroup *group)
-{
-  /* FPS register's type is INT, but belongs to float_reggroup.  Beside
-     this, FPS register belongs to save_regroup, restore_reggroup, and
-     all_reggroup, of course.  */
-  if (regnum == ARM_FPS_REGNUM)
-    return (group == float_reggroup
-	    || group == save_reggroup
-	    || group == restore_reggroup
-	    || group == all_reggroup);
-  else
-    return default_register_reggroup_p (gdbarch, regnum, group);
-}
-
-/* For backward-compatibility we allow two 'g' packet lengths with
-   the remote protocol depending on whether FPA registers are
-   supplied.  M-profile targets do not have FPA registers, but some
-   stubs already exist in the wild which use a 'g' packet which
-   supplies them albeit with dummy values.  The packet format which
-   includes FPA registers should be considered deprecated for
-   M-profile targets.  */
-
-static void
-arm_register_g_packet_guesses (struct gdbarch *gdbarch)
-{
-  arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
-
-  if (tdep->is_m)
-    {
-      const target_desc *tdesc;
-
-      /* If we know from the executable this is an M-profile target,
-	 cater for remote targets whose register set layout is the
-	 same as the FPA layout.  */
-      tdesc = arm_read_mprofile_description (ARM_M_TYPE_WITH_FPA);
-      register_remote_g_packet_guess (gdbarch,
-				      ARM_CORE_REGS_SIZE + ARM_FP_REGS_SIZE,
-				      tdesc);
-
-      /* The regular M-profile layout.  */
-      tdesc = arm_read_mprofile_description (ARM_M_TYPE_M_PROFILE);
-      register_remote_g_packet_guess (gdbarch, ARM_CORE_REGS_SIZE,
-				      tdesc);
-
-      /* M-profile plus M4F VFP.  */
-      tdesc = arm_read_mprofile_description (ARM_M_TYPE_VFP_D16);
-      register_remote_g_packet_guess (gdbarch,
-				      ARM_CORE_REGS_SIZE + ARM_VFP2_REGS_SIZE,
-				      tdesc);
-      /* M-profile plus MVE.  */
-      tdesc = arm_read_mprofile_description (ARM_M_TYPE_MVE);
-      register_remote_g_packet_guess (gdbarch, ARM_CORE_REGS_SIZE
-				      + ARM_VFP2_REGS_SIZE
-				      + ARM_INT_REGISTER_SIZE, tdesc);
-
-      /* M-profile system (stack pointers).  */
-      tdesc = arm_read_mprofile_description (ARM_M_TYPE_SYSTEM);
-      register_remote_g_packet_guess (gdbarch, 2 * ARM_INT_REGISTER_SIZE, tdesc);
-    }
-
-  /* Otherwise we don't have a useful guess.  */
-}
-
 /* Implement the code_of_frame_writable gdbarch method.  */
 
 static int
@@ -9848,7 +9634,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   bool have_s_pseudos = false, have_q_pseudos = false;
   bool have_wmmx_registers = false;
   bool have_neon = false;
-  bool have_fpa_registers = true;
   const struct target_desc *tdesc = info.target_desc;
   bool have_vfp = false;
   bool have_mve = false;
@@ -10015,21 +9800,13 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	    {
 	      switch (e_flags & (EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT))
 		{
-		case 0:
-		  /* Leave it as "auto".  Strictly speaking this case
-		     means FPA, but almost nobody uses that now, and
-		     many toolchains fail to set the appropriate bits
-		     for the floating-point model they use.  */
-		  break;
-		case EF_ARM_SOFT_FLOAT:
-		  fp_model = ARM_FLOAT_SOFT_FPA;
+		case 0: /* Default to soft-float VFP.  */
+		case EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT:
+		  fp_model = ARM_FLOAT_SOFT_VFP;
 		  break;
 		case EF_ARM_VFP_FLOAT:
 		  fp_model = ARM_FLOAT_VFP;
 		  break;
-		case EF_ARM_SOFT_FLOAT | EF_ARM_VFP_FLOAT:
-		  fp_model = ARM_FLOAT_SOFT_VFP;
-		  break;
 		}
 	    }
 
@@ -10122,20 +9899,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 	    }
 	}
 
-      feature = tdesc_find_feature (tdesc,
-				    "org.gnu.gdb.arm.fpa");
-      if (feature != NULL)
-	{
-	  valid_p = 1;
-	  for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
-	    valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
-						arm_register_names[i]);
-	  if (!valid_p)
-	    return NULL;
-	}
-      else
-	have_fpa_registers = false;
-
       feature = tdesc_find_feature (tdesc,
 				    "org.gnu.gdb.xscale.iwmmxt");
       if (feature != NULL)
@@ -10389,7 +10152,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->fp_model = fp_model;
   tdep->is_m = is_m;
   tdep->have_sec_ext = have_sec_ext;
-  tdep->have_fpa_registers = have_fpa_registers;
   tdep->have_wmmx_registers = have_wmmx_registers;
   gdb_assert (vfp_register_count == 0
 	      || vfp_register_count == 16
@@ -10421,8 +10183,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       tdep->m_profile_psp_s_regnum = m_profile_psp_s_regnum;
     }
 
-  arm_register_g_packet_guesses (gdbarch);
-
   /* Breakpoints.  */
   switch (info.byte_order_for_code)
     {
@@ -10508,12 +10268,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
   set_gdbarch_num_regs (gdbarch, register_count);
   set_gdbarch_register_type (gdbarch, arm_register_type);
-  set_gdbarch_register_reggroup_p (gdbarch, arm_register_reggroup_p);
-
-  /* This "info float" is FPA-specific.  Use the generic version if we
-     do not have FPA.  */
-  if (tdep->have_fpa_registers)
-    set_gdbarch_print_float_info (gdbarch, arm_print_float_info);
 
   /* Internal <-> external register number maps.  */
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, arm_dwarf_reg_to_regnum);
@@ -10565,29 +10319,13 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Watchpoints are not steppable.  */
   set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
 
-  /* We used to default to FPA for generic ARM, but almost nobody
-     uses that now, and we now provide a way for the user to force
-     the model.  So default to the most useful variant.  */
-  if (tdep->fp_model == ARM_FLOAT_AUTO)
-    tdep->fp_model = ARM_FLOAT_SOFT_FPA;
-
   if (tdep->jb_pc >= 0)
     set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target);
 
   /* Floating point sizes and format.  */
   set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
-  if (tdep->fp_model == ARM_FLOAT_SOFT_FPA || tdep->fp_model == ARM_FLOAT_FPA)
-    {
-      set_gdbarch_double_format
-	(gdbarch, floatformats_ieee_double_littlebyte_bigword);
-      set_gdbarch_long_double_format
-	(gdbarch, floatformats_ieee_double_littlebyte_bigword);
-    }
-  else
-    {
-      set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
-      set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
-    }
+  set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
+  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
 
   /* Hook used to decorate frames with signed return addresses, only available
      for ARMv8.1-m PACBTI.  */
@@ -10678,8 +10416,6 @@ arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 
   gdb_printf (file, _("arm_dump_tdep: fp_model = %i\n"),
 	      (int) tdep->fp_model);
-  gdb_printf (file, _("arm_dump_tdep: have_fpa_registers = %i\n"),
-	      (int) tdep->have_fpa_registers);
   gdb_printf (file, _("arm_dump_tdep: have_wmmx_registers = %i\n"),
 	      (int) tdep->have_wmmx_registers);
   gdb_printf (file, _("arm_dump_tdep: vfp_register_count = %i\n"),
@@ -10820,8 +10556,6 @@ _initialize_arm_tdep ()
 			_("Set the floating point type."),
 			_("Show the floating point type."),
 			_("auto - Determine the FP typefrom the OS-ABI.\n\
-softfpa - Software FP, mixed-endian doubles on little-endian ARMs.\n\
-fpa - FPA co-processor (GCC compiled).\n\
 softvfp - Software FP with pure-endian doubles.\n\
 vfp - VFP co-processor."),
 			set_fp_model_sfunc, show_fp_model,
diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
index 67dd1151da4..594961e52ec 100644
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -62,8 +62,6 @@ extern bool arm_apcs_32;
 enum arm_float_model
 {
   ARM_FLOAT_AUTO,	/* Automatic detection.  Do not set in tdep.  */
-  ARM_FLOAT_SOFT_FPA,	/* Traditional soft-float (mixed-endian on LE ARM).  */
-  ARM_FLOAT_FPA,	/* FPA co-processor.  GCC calling convention.  */
   ARM_FLOAT_SOFT_VFP,	/* Soft-float with pure-endian doubles.  */
   ARM_FLOAT_VFP,	/* Full VFP calling convention.  */
   ARM_FLOAT_LAST	/* Keep at end.  */
@@ -95,7 +93,6 @@ struct arm_gdbarch_tdep : gdbarch_tdep_base
 
   enum arm_float_model fp_model {}; /* Floating point calling conventions.  */
 
-  bool have_fpa_registers = false;	/* Does the target report the FPA registers?  */
   bool have_wmmx_registers = false;	/* Does the target report the WMMX registers?  */
   /* The number of VFP registers reported by the target.  It is zero
      if VFP registers are not supported.  */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 238a49b027d..2111a584b88 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -25309,11 +25309,6 @@ argument @var{fputype} can be one of these:
 @table @code
 @item auto
 Determine the FPU type by querying the OS ABI.
-@item softfpa
-Software FPU, with mixed-endian doubles on little-endian ARM
-processors.
-@item fpa
-GCC-compiled FPA co-processor.
 @item softvfp
 Software FPU with pure-endian doubles.
 @item vfp
@@ -46919,9 +46914,6 @@ Double precision IEEE floating point.
 @item bfloat16
 The 16-bit @dfn{brain floating point} format used e.g.@: by x86 and ARM.
 
-@item arm_fpa_ext
-The 12-byte extended precision format used by ARM FPA registers.
-
 @item i387_ext
 The 10-byte extended precision format used by x87 registers.
 
@@ -47106,8 +47098,9 @@ feature is replaced by @samp{org.gnu.gdb.arm.m-profile}.  It should contain
 registers @samp{r0} through @samp{r13}, @samp{sp}, @samp{lr}, @samp{pc},
 and @samp{xpsr}.
 
-The @samp{org.gnu.gdb.arm.fpa} feature is optional.  If present, it
-should contain registers @samp{f0} through @samp{f7} and @samp{fps}.
+The @samp{org.gnu.gdb.arm.fpa} feature is no longer supported.  It
+used to contain registers @samp{f0} through @samp{f7} and @samp{fps}, for the
+legacy FPA feature.
 
 The @samp{org.gnu.gdb.arm.m-profile-mve} feature is optional.  If present, it
 must contain register @samp{vpr}.
diff --git a/gdb/features/Makefile b/gdb/features/Makefile
index 061cb2ed032..3d0ed4edafa 100644
--- a/gdb/features/Makefile
+++ b/gdb/features/Makefile
@@ -204,11 +204,9 @@ FEATURE_XMLFILES = aarch64-core.xml \
 	arc/v2-core.xml \
 	arc/v2-aux.xml \
 	arm/arm-core.xml \
-	arm/arm-fpa.xml \
 	arm/arm-m-profile.xml \
 	arm/arm-m-profile-mve.xml \
 	arm/arm-m-system.xml \
-	arm/arm-m-profile-with-fpa.xml \
 	arm/arm-tls.xml \
 	arm/arm-vfpv2.xml \
 	arm/arm-vfpv3.xml \
diff --git a/gdb/features/arm/arm-fpa.c b/gdb/features/arm/arm-fpa.c
deleted file mode 100644
index 65a49f5f3f1..00000000000
--- a/gdb/features/arm/arm-fpa.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
-  Original: arm-fpa.xml */
-
-#include "gdbsupport/tdesc.h"
-
-static int
-create_feature_arm_arm_fpa (struct target_desc *result, long regnum)
-{
-  struct tdesc_feature *feature;
-
-  feature = tdesc_create_feature (result, "org.gnu.gdb.arm.fpa");
-  regnum = 16;
-  tdesc_create_reg (feature, "f0", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "f1", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "f2", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "f3", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "f4", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "f5", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "f6", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "f7", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "fps", regnum++, 1, NULL, 32, "int");
-  return regnum;
-}
diff --git a/gdb/features/arm/arm-fpa.xml b/gdb/features/arm/arm-fpa.xml
deleted file mode 100644
index d533b25132f..00000000000
--- a/gdb/features/arm/arm-fpa.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0"?>
-<!-- Copyright (C) 2007-2022 Free Software Foundation, Inc.
-
-     Copying and distribution of this file, with or without modification,
-     are permitted in any medium without royalty provided the copyright
-     notice and this notice are preserved.  -->
-
-<!DOCTYPE feature SYSTEM "gdb-target.dtd">
-<feature name="org.gnu.gdb.arm.fpa">
-  <!-- f0's regnum is set explicitly, because the FPA registers
-       historically were placed between the PC and the CPSR in the "g"
-       packet - in the middle of org.gnu.gdb.arm.core.  -->
-  <reg name="f0" bitsize="96" type="arm_fpa_ext" regnum="16"/>
-  <reg name="f1" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="f2" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="f3" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="f4" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="f5" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="f6" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="f7" bitsize="96" type="arm_fpa_ext"/>
-
-  <reg name="fps" bitsize="32"/>
-</feature>
diff --git a/gdb/features/arm/arm-m-profile-with-fpa.c b/gdb/features/arm/arm-m-profile-with-fpa.c
deleted file mode 100644
index 2b7c78597bb..00000000000
--- a/gdb/features/arm/arm-m-profile-with-fpa.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
-  Original: arm-m-profile-with-fpa.xml */
-
-#include "gdbsupport/tdesc.h"
-
-static int
-create_feature_arm_arm_m_profile_with_fpa (struct target_desc *result, long regnum)
-{
-  struct tdesc_feature *feature;
-
-  feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-profile");
-  tdesc_create_reg (feature, "r0", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r1", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r2", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r3", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r4", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r5", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r6", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r7", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r8", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r9", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r10", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r11", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "r12", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "sp", regnum++, 1, NULL, 32, "data_ptr");
-  tdesc_create_reg (feature, "lr", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "pc", regnum++, 1, NULL, 32, "code_ptr");
-  tdesc_create_reg (feature, "", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "", regnum++, 1, NULL, 96, "arm_fpa_ext");
-  tdesc_create_reg (feature, "", regnum++, 1, NULL, 32, "int");
-  tdesc_create_reg (feature, "xpsr", regnum++, 1, NULL, 32, "int");
-  return regnum;
-}
diff --git a/gdb/features/arm/arm-m-profile-with-fpa.xml b/gdb/features/arm/arm-m-profile-with-fpa.xml
deleted file mode 100644
index 850ed42cbfd..00000000000
--- a/gdb/features/arm/arm-m-profile-with-fpa.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0"?>
-<!-- Copyright (C) 2019-2022 Free Software Foundation, Inc.
-
-     Copying and distribution of this file, with or without modification,
-     are permitted in any medium without royalty provided the copyright
-     notice and this notice are preserved.  -->
-
-<!DOCTYPE feature SYSTEM "gdb-target.dtd">
-<feature name="org.gnu.gdb.arm.m-profile">
-  <reg name="r0" bitsize="32"/>
-  <reg name="r1" bitsize="32"/>
-  <reg name="r2" bitsize="32"/>
-  <reg name="r3" bitsize="32"/>
-  <reg name="r4" bitsize="32"/>
-  <reg name="r5" bitsize="32"/>
-  <reg name="r6" bitsize="32"/>
-  <reg name="r7" bitsize="32"/>
-  <reg name="r8" bitsize="32"/>
-  <reg name="r9" bitsize="32"/>
-  <reg name="r10" bitsize="32"/>
-  <reg name="r11" bitsize="32"/>
-  <reg name="r12" bitsize="32"/>
-  <reg name="sp" bitsize="32" type="data_ptr"/>
-  <reg name="lr" bitsize="32"/>
-  <reg name="pc" bitsize="32" type="code_ptr"/>
-
-  <!-- Slack for unused FPA registers (f0-f7 + fps).  -->
-  <reg name="" bitsize="96" type="arm_fpa_ext" regnum="16"/>
-  <reg name="" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="" bitsize="96" type="arm_fpa_ext"/>
-  <reg name="" bitsize="32"/>
-
-  <reg name="xpsr" bitsize="32" regnum="25"/>
-</feature>
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 044b171ecd2..45a3df941c5 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -132,10 +132,6 @@ make_gdb_type (struct gdbarch *gdbarch, struct tdesc_type *ttype)
 	  m_type = arch_float_type (m_gdbarch, -1, "builtin_type_ieee_double",
 				    floatformats_ieee_double);
 	  return;
-	case TDESC_TYPE_ARM_FPA_EXT:
-	  m_type = arch_float_type (m_gdbarch, -1, "builtin_type_arm_ext",
-				    floatformats_arm_ext);
-	  return;
 
 	case TDESC_TYPE_I387_EXT:
 	  m_type = arch_float_type (m_gdbarch, -1, "builtin_type_i387_ext",
diff --git a/gdb/testsuite/gdb.base/long_long.exp b/gdb/testsuite/gdb.base/long_long.exp
index 9c8dd16b7eb..bb4c1a1859e 100644
--- a/gdb/testsuite/gdb.base/long_long.exp
+++ b/gdb/testsuite/gdb.base/long_long.exp
@@ -141,22 +141,10 @@ gdb_test_ptr "p/a val.oct" "" "" "0x77053977" "0xa72ee53977053977"
 gdb_test "p/c val.oct" "'w'"
 
 if { $sizeof_double == 8 || $sizeof_long_double == 8 } {
-    # ARM FPA floating point numbers are not strictly little endian or big
-    # endian, but a hybrid.  They are in little endian format with the two
-    # words swapped in big endian format.
     # EABI targets default to natural-endian VFP format.
-
-    if { ([istarget "arm*-*-*"]) \
-	 && !([istarget "*-*-*eabi*"] || \
-	      [istarget "*-*-mingw32ce*"] || \
-	      [istarget "*-*-openbsd*"]) } then {
-	# assume the long long represents a floating point double in ARM format
-	gdb_test "p/f val.oct" "2.1386676354387559e\\+265"
-    } else {
-	# assume the long long represents a floating point double in little
-	# endian format
-	gdb_test "p/f val.oct" "-5.9822653797615723e-120"
-    }
+    # Assume the long long represents a floating point double in little
+    # endian format
+    gdb_test "p/f val.oct" "-5.9822653797615723e-120"
 } else {
     gdb_test "p/f val.oct" "-2.42716126e-15"
 }
diff --git a/gdbserver/linux-arm-low.cc b/gdbserver/linux-arm-low.cc
index ab6209a3abc..fb3f02088ca 100644
--- a/gdbserver/linux-arm-low.cc
+++ b/gdbserver/linux-arm-low.cc
@@ -983,8 +983,7 @@ arm_read_description (void)
 	return arm_linux_read_description (ARM_FP_TYPE_VFPV2);
     }
 
-  /* The default configuration uses legacy FPA registers, probably
-     simulated.  */
+  /* No floating point registers.  */
   return arm_linux_read_description (ARM_FP_TYPE_NONE);
 }
 
@@ -1088,9 +1087,9 @@ static struct regset_info arm_regsets[] = {
   { PTRACE_GETREGS, PTRACE_SETREGS, 0,
     ARM_CORE_REGS_SIZE + ARM_INT_REGISTER_SIZE, GENERAL_REGS,
     arm_fill_gregset, arm_store_gregset },
-  { PTRACE_GETWMMXREGS, PTRACE_SETWMMXREGS, 0, IWMMXT_REGS_SIZE, EXTENDED_REGS,
+  { PTRACE_GETWMMXREGS, PTRACE_SETWMMXREGS, 0, IWMMXT_REGS_SIZE, OPTIONAL_REGS,
     arm_fill_wmmxregset, arm_store_wmmxregset },
-  { PTRACE_GETVFPREGS, PTRACE_SETVFPREGS, 0, ARM_VFP3_REGS_SIZE, EXTENDED_REGS,
+  { PTRACE_GETVFPREGS, PTRACE_SETVFPREGS, 0, ARM_VFP3_REGS_SIZE, OPTIONAL_REGS,
     arm_fill_vfpregset, arm_store_vfpregset },
   NULL_REGSET
 };
diff --git a/gdbsupport/tdesc.cc b/gdbsupport/tdesc.cc
index 4d41d0b168a..0b0b765cb3d 100644
--- a/gdbsupport/tdesc.cc
+++ b/gdbsupport/tdesc.cc
@@ -53,7 +53,6 @@ static tdesc_type_builtin tdesc_predefined_types[] =
   { "ieee_half", TDESC_TYPE_IEEE_HALF },
   { "ieee_single", TDESC_TYPE_IEEE_SINGLE },
   { "ieee_double", TDESC_TYPE_IEEE_DOUBLE },
-  { "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT },
   { "i387_ext", TDESC_TYPE_I387_EXT },
   { "bfloat16", TDESC_TYPE_BFLOAT16 }
 };
diff --git a/gdbsupport/tdesc.h b/gdbsupport/tdesc.h
index 403aa2c3d19..082819ada13 100644
--- a/gdbsupport/tdesc.h
+++ b/gdbsupport/tdesc.h
@@ -171,7 +171,6 @@ enum tdesc_type_kind
   TDESC_TYPE_IEEE_HALF,
   TDESC_TYPE_IEEE_SINGLE,
   TDESC_TYPE_IEEE_DOUBLE,
-  TDESC_TYPE_ARM_FPA_EXT,
   TDESC_TYPE_I387_EXT,
   TDESC_TYPE_BFLOAT16,
 
