aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2009-11-02 13:44:05 +0000
committerPaul Brook <paul@codesourcery.com>2009-11-02 13:44:05 +0000
commit62f3b8c86784407e864ddf7698b9852cb76aa339 (patch)
tree6a7acbf09e26521be68c3b7f3a49fe3ccc90a339 /bfd
parentec15ac506168c7b0ead70d5d52c5d3fd18c5acab (diff)
downloadgdb-62f3b8c86784407e864ddf7698b9852cb76aa339.zip
gdb-62f3b8c86784407e864ddf7698b9852cb76aa339.tar.gz
gdb-62f3b8c86784407e864ddf7698b9852cb76aa339.tar.bz2
2009-11-02 Paul Brook <paul@codesourcery.com>
ld/testsuite/ * ld-arm/arm-elf.exp: Add new attr-merge-vfp tests. * ld-arm/attr-merge-vfp-1.d: New test. * ld-arm/attr-merge-vfp-1r.d: New test. * ld-arm/attr-merge-vfp-2.d: New test. * ld-arm/attr-merge-vfp-2r.d: New test. * ld-arm/attr-merge-vfp-3.d: New test. * ld-arm/attr-merge-vfp-3r.d: New test. * ld-arm/attr-merge-vfp-4.d: New test. * ld-arm/attr-merge-vfp-4r.d: New test. * ld-arm/attr-merge-vfp-5.d: New test. * ld-arm/attr-merge-vfp-5r.d: New test. * ld-arm/attr-merge-vfp-2.s: New test. * ld-arm/attr-merge-vfp-3.s: New test. * ld-arm/attr-merge-vfp-3-d16.s: New test. * ld-arm/attr-merge-vfp-4.s: New test. * ld-arm/attr-merge-vfp-4-d16.s: New test. gas/ * doc/c-arm.texi: Document new -mfpu options. * config/tc-arm.c (fpu_vfp_ext_v3xd, fpu_vfp_fp16, fpu_neon_ext_fma, fpu_vfp_ext_fma): New. (NEON_ENC_TAB): Add vfma, vfms, vfnma and vfnms. (do_vfp_nsyn_fma_fms, do_neon_fmac): New functions. (insns): Move double precision load/store. Split out double precision VFPv3 instrucitons. Add VFPv4 instructions. (arm_fpus): Add VFPv3-FP16, VFPv3xD and VFPv4 variants. (aeabi_set_public_attributes): Set VFPv4 variants gas/testsuite/ * gas/arm/attr-mfpu-vfpv4.d: New test. * gas/arm/attr-mfpu-vfpv4-d16.d: New test. * gas/arm/neon-fma-cov.d: New test. * gas/arm/neon-fma-cov.s: New test. * gas/arm/vfp-fma-inc.s: New test. * gas/arm/vfp-fma-arm.d: New test. * gas/arm/vfp-fma-arm.s: New test. * gas/arm/vfp-fma-thumb.d: New test. * gas/arm/vfp-fma-thumb.s: New test. * gas/arm/vfma1.d: New test. * gas/arm/vfma1.s: New test. * gas/arm/vfpv3xd.d: New test. * gas/arm/vfpv3xd.s: New test. include/opcode/ * arm.h (FPU_VFP_EXT_V3xD, FPU_VFP_EXT_FP16, FPU_NEON_EXT_FMA, FPU_VFP_EXT_FMA, FPU_VFP_V3xD, FPU_VFP_V4D16, FPU_VFP_V4): Define. (FPU_ARCH_VFP_V3D16_FP16, FPU_ARCH_VFP_V3_FP16, FPU_ARCH_VFP_V3xD, FPU_ARCH_VFP_V3xD_FP16, FPU_ARCH_VFP_V4, FPU_ARCH_VFP_V4D16, FPU_ARCH_NEON_VFP_V4): Define. binutils/ * readelf.c (arm_attr_tag_VFP_arch): Add VFPv4 and VFPv4-D16. bfd/ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Handle VFPv4 attributes. opcodes/ * arm-dis.c (coprocessor_opcodes): Update to use new feature flags. Add VFPv4 instructions.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf32-arm.c52
2 files changed, 49 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 52265cb..ce48a24 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-02 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.c (elf32_arm_merge_eabi_attributes): Handle VFPv4
+ attributes.
+
2009-11-02 Alan Modra <amodra@bigpond.net.au>
* elflink.c (elf_link_add_object_symbols): Don't force debug
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index b449ee8..caa3bd2 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -9730,8 +9730,6 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
/* Some tags have 0 = don't care, 1 = strong requirement,
2 = weak requirement. */
static const int order_021[3] = {0, 2, 1};
- /* For use with Tag_VFP_arch. */
- static const int order_01243[5] = {0, 1, 2, 4, 3};
int i;
bfd_boolean result = TRUE;
@@ -9923,12 +9921,50 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
}
break;
case Tag_VFP_arch:
- /* Use the "greatest" from the sequence 0, 1, 2, 4, 3, or the
- largest value if greater than 4 (for future-proofing). */
- if ((in_attr[i].i > 4 && in_attr[i].i > out_attr[i].i)
- || (in_attr[i].i <= 4 && out_attr[i].i <= 4
- && order_01243[in_attr[i].i] > order_01243[out_attr[i].i]))
- out_attr[i].i = in_attr[i].i;
+ {
+ static const struct
+ {
+ int ver;
+ int regs;
+ } vfp_versions[7] =
+ {
+ {0, 0},
+ {1, 16},
+ {2, 16},
+ {3, 32},
+ {3, 16},
+ {4, 32},
+ {4, 16}
+ };
+ int ver;
+ int regs;
+ int newval;
+
+ /* Values greater than 6 aren't defined, so just pick the
+ biggest */
+ if (in_attr[i].i > 6 && in_attr[i].i > out_attr[i].i)
+ {
+ out_attr[i] = in_attr[i];
+ break;
+ }
+ /* The output uses the superset of input features
+ (ISA version) and registers. */
+ ver = vfp_versions[in_attr[i].i].ver;
+ if (ver < vfp_versions[out_attr[i].i].ver)
+ ver = vfp_versions[out_attr[i].i].ver;
+ regs = vfp_versions[in_attr[i].i].regs;
+ if (regs < vfp_versions[out_attr[i].i].regs)
+ regs = vfp_versions[out_attr[i].i].regs;
+ /* This assumes all possible supersets are also a valid
+ options. */
+ for (newval = 6; newval > 0; newval--)
+ {
+ if (regs == vfp_versions[newval].regs
+ && ver == vfp_versions[newval].ver)
+ break;
+ }
+ out_attr[i].i = newval;
+ }
break;
case Tag_PCS_config:
if (out_attr[i].i == 0)