This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ARM VFPv3-D16 support


The attached patch adds binutils support for the ARM VFPv3-D16 coprocessor.
This is a variant of VFPv3 with only 16 double precision registers.

Applied to cvs head.

Paul

2008-03-09  Paul Brook  <paul@codesourcery.com>

	bfd/
	* elf32-arm.c (elf32_arm_merge_eabi_attributes): Handle new
	Tag_VFP_arch values.

	binutils/
	* readelf.c (arm_attr_tag_VFP_arch): Add "VFPv3-D16".

	gas/
	* config/tc-arm.c (fpu_vfp_ext_d32): New vairable.
	(parse_vfp_reg_list, encode_arm_vfp_reg): Use it.
	(arm_option_cpu_value): Add vfpv3-d16, vfpv2 and vfpv3.
	(aeabi_set_public_attributes): Handle Tag_VFP_arch=VFPV3-D16.
	* doc/c-arm.texi: Document new ARM FPU variants.

	gas/testsuite/
	* gas/arm/vfpv3-d16-bad.d: New test.
	* gas/arm/vfpv3-d16-bad.l: New test.

	include/opcode/
	* arm.h (FPU_VFP_EXT_D32, FPU_VFP_V3D16, FPU_ARCH_VFP_V3D16): Define.
Index: bfd/elf32-arm.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elf32-arm.c,v
retrieving revision 1.138
diff -u -p -r1.138 elf32-arm.c
--- bfd/elf32-arm.c	8 Mar 2008 14:58:14 -0000	1.138
+++ bfd/elf32-arm.c	8 Mar 2008 17:13:06 -0000
@@ -6902,6 +6902,8 @@ elf32_arm_merge_eabi_attributes (bfd *ib
   /* Some tags have 0 = don't care, 1 = strong requirement,
      2 = weak requirement.  */
   static const int order_312[3] = {3, 1, 2};
+  /* For use with Tag_VFP_arch.  */
+  static const int order_01243[5] = {0, 1, 2, 4, 3};
   int i;
 
   if (!elf_known_obj_attributes_proc (obfd)[0].i)
@@ -6956,7 +6958,6 @@ elf32_arm_merge_eabi_attributes (bfd *ib
 	case Tag_CPU_arch:
 	case Tag_ARM_ISA_use:
 	case Tag_THUMB_ISA_use:
-	case Tag_VFP_arch:
 	case Tag_WMMX_arch:
 	case Tag_NEON_arch:
 	  /* ??? Do NEON and WMMX conflict?  */
@@ -6984,6 +6985,11 @@ elf32_arm_merge_eabi_attributes (bfd *ib
 	  if (in_attr[i].i)
 	    out_attr[i].i = in_attr[i].i;
 	  break;
+	case Tag_VFP_arch:
+	  if (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;
+	  break;
 	case Tag_PCS_config:
 	  if (out_attr[i].i == 0)
 	    out_attr[i].i = in_attr[i].i;
Index: binutils/readelf.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/binutils/readelf.c,v
retrieving revision 1.400
diff -u -p -r1.400 readelf.c
--- binutils/readelf.c	4 Feb 2008 19:16:53 -0000	1.400
+++ binutils/readelf.c	8 Mar 2008 17:13:06 -0000
@@ -8628,8 +8628,8 @@ static const char *arm_attr_tag_CPU_arch
 static const char *arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
 static const char *arm_attr_tag_THUMB_ISA_use[] =
   {"No", "Thumb-1", "Thumb-2"};
-/* FIXME: VFPv3 encoding was extrapolated!  */
-static const char *arm_attr_tag_VFP_arch[] = {"No", "VFPv1", "VFPv2", "VFPv3"};
+static const char *arm_attr_tag_VFP_arch[] =
+  {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16"};
 static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1"};
 static const char *arm_attr_tag_NEON_arch[] = {"No", "NEONv1"};
 static const char *arm_attr_tag_ABI_PCS_config[] =
Index: gas/config/tc-arm.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/config/tc-arm.c,v
retrieving revision 1.350
diff -u -p -r1.350 tc-arm.c
--- gas/config/tc-arm.c	8 Mar 2008 01:20:38 -0000	1.350
+++ gas/config/tc-arm.c	8 Mar 2008 18:06:25 -0000
@@ -221,6 +221,8 @@ static const arm_feature_set fpu_vfp_ext
 static const arm_feature_set fpu_vfp_ext_v1 = ARM_FEATURE (0, FPU_VFP_EXT_V1);
 static const arm_feature_set fpu_vfp_ext_v2 = ARM_FEATURE (0, FPU_VFP_EXT_V2);
 static const arm_feature_set fpu_vfp_ext_v3 = ARM_FEATURE (0, FPU_VFP_EXT_V3);
+static const arm_feature_set fpu_vfp_ext_d32 =
+  ARM_FEATURE (0, FPU_VFP_EXT_D32);
 static const arm_feature_set fpu_neon_ext_v1 = ARM_FEATURE (0, FPU_NEON_EXT_V1);
 static const arm_feature_set fpu_vfp_v3_or_neon_ext =
   ARM_FEATURE (0, FPU_NEON_EXT_V1 | FPU_VFP_EXT_V3);
@@ -1607,16 +1609,16 @@ parse_vfp_reg_list (char **ccp, unsigned
 
   if (etype != REGLIST_VFP_S)
     {
-      /* VFPv3 allows 32 D registers.  */
-      if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
+      /* VFPv3 allows 32 D registers, except for the VFPv3-D16 variant.  */
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
         {
           max_regs = 32;
           if (thumb_mode)
             ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
-                                    fpu_vfp_ext_v3);
+                                    fpu_vfp_ext_d32);
           else
             ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
-                                    fpu_vfp_ext_v3);
+                                    fpu_vfp_ext_d32);
         }
       else
         max_regs = 16;
@@ -6161,14 +6163,14 @@ encode_arm_vfp_reg (int reg, enum vfp_re
   if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
       && reg > 15)
     {
-      if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
+      if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
         {
           if (thumb_mode)
             ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
-                                    fpu_vfp_ext_v3);
+                                    fpu_vfp_ext_d32);
           else
             ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
-                                    fpu_vfp_ext_v3);
+                                    fpu_vfp_ext_d32);
         }
       else
         {
@@ -20211,10 +20213,13 @@ static const struct arm_option_cpu_value
   {"softvfp+vfp",	FPU_ARCH_VFP_V2},
   {"vfp",		FPU_ARCH_VFP_V2},
   {"vfp9",		FPU_ARCH_VFP_V2},
-  {"vfp3",              FPU_ARCH_VFP_V3},
+  {"vfp3",              FPU_ARCH_VFP_V3}, /* For backwards compatbility.  */
   {"vfp10",		FPU_ARCH_VFP_V2},
   {"vfp10-r0",		FPU_ARCH_VFP_V1},
   {"vfpxd",		FPU_ARCH_VFP_V1xD},
+  {"vfpv2",		FPU_ARCH_VFP_V2},
+  {"vfpv3",		FPU_ARCH_VFP_V3},
+  {"vfpv3-d16",		FPU_ARCH_VFP_V3D16},
   {"arm1020t",		FPU_ARCH_VFP_V1},
   {"arm1020e",		FPU_ARCH_VFP_V2},
   {"arm1136jfs",	FPU_ARCH_VFP_V2},
@@ -20675,7 +20680,10 @@ aeabi_set_public_attributes (void)
     bfd_elf_add_proc_attr_int (stdoutput, 9,
 	ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2) ? 2 : 1);
   /* Tag_VFP_arch.  */
-  if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_vfp_ext_v3)
+  if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_vfp_ext_d32)
+      || ARM_CPU_HAS_FEATURE (arm_arch_used, fpu_vfp_ext_d32))
+    bfd_elf_add_proc_attr_int (stdoutput, 10, 4);
+  else if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_vfp_ext_v3)
       || ARM_CPU_HAS_FEATURE (arm_arch_used, fpu_vfp_ext_v3))
     bfd_elf_add_proc_attr_int (stdoutput, 10, 3);
   else if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_vfp_ext_v2)
Index: gas/doc/c-arm.texi
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/doc/c-arm.texi,v
retrieving revision 1.47
diff -u -p -r1.47 c-arm.texi
--- gas/doc/c-arm.texi	20 Feb 2008 15:17:56 -0000	1.47
+++ gas/doc/c-arm.texi	8 Mar 2008 18:06:25 -0000
@@ -190,11 +190,15 @@ The following format options are recogni
 @code{vfp10-r0},
 @code{vfp9},
 @code{vfpxd},
+@code{vfpv2}
+@code{vfpv3}
+@code{vfpv3-d16}
 @code{arm1020t},
 @code{arm1020e},
-@code{arm1136jf-s}
+@code{arm1136jf-s},
+@code{maverick}
 and
-@code{maverick}.
+@code{neon}.
 
 In addition to determining which instructions are assembled, this option
 also affects the way in which the @code{.double} assembler directive behaves
Index: gas/testsuite/gas/arm/vfpv3-d16-bad.d
===================================================================
RCS file: gas/testsuite/gas/arm/vfpv3-d16-bad.d
diff -N gas/testsuite/gas/arm/vfpv3-d16-bad.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/vfpv3-d16-bad.d	8 Mar 2008 18:06:25 -0000
@@ -0,0 +1,4 @@
+# name: VFPv3-D16
+# as: -mfpu=vfpv3-d16
+# error-output: vfpv3-d16-bad.l
+# source: vfpv3-32drs.s
Index: gas/testsuite/gas/arm/vfpv3-d16-bad.l
===================================================================
RCS file: gas/testsuite/gas/arm/vfpv3-d16-bad.l
diff -N gas/testsuite/gas/arm/vfpv3-d16-bad.l
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/vfpv3-d16-bad.l	8 Mar 2008 17:13:06 -0000
@@ -0,0 +1,53 @@
+[^:]*: Assembler messages:
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcpyd d3,d22'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcpyd d22,d3'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcvtds d22,s22'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcvtsd s22,d22'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmdhr d21,r4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmdlr d27,r5'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmrdh r6,d23'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmrdl r7,d25'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fsitod d22,s22'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fuitod d21,s21'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `ftosid s20,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `ftosizd s20,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `ftouid s19,d19'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `ftouizd s19,d19'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fldd d19,\[r10,#4\]'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fstd d21,\[r10,#4\]'
+[^:]*:[0-9]+: Error: register out of range in list -- `fldmiad r10!,\{d18,d19,d20\}'
+[^:]*:[0-9]+: Error: register out of range in list -- `fldmiax r10!,\{d18,d19,d20\}'
+[^:]*:[0-9]+: Error: register out of range in list -- `fldmdbx r10!,\{d18,d19\}'
+[^:]*:[0-9]+: Error: register out of range in list -- `fstmiad r9,\{d20,d21,d22,d23,d24\}'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fabsd d12,d18'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fabsd d18,d19'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fnegd d12,d18'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fnegd d18,d19'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fsqrtd d12,d18'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fsqrtd d18,d19'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `faddd d12,d18,d4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `faddd d18,d19,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fsubd d12,d18,d4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fsubd d18,d19,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmuld d12,d18,d4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmuld d18,d19,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fdivd d12,d18,d4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fdivd d18,d19,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmacd d12,d18,d4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmacd d18,d19,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmscd d12,d18,d4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmscd d18,d19,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fnmuld d12,d18,d4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fnmuld d18,d19,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fnmacd d12,d18,d4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fnmacd d18,d19,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fnmscd d12,d18,d4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fnmscd d18,d19,d20'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcmpd d3,d18'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcmpd d18,d3'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcmpzd d19'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcmped d3,d18'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcmped d18,d3'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fcmpezd d19'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmdrr d31,r3,r4'
+[^:]*:[0-9]+: Error: D register out of range for selected VFP version -- `fmrrd r5,r6,d30'
Index: include/opcode/arm.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/include/opcode/arm.h,v
retrieving revision 1.12
diff -u -p -r1.12 arm.h
--- include/opcode/arm.h	5 Mar 2008 01:31:26 -0000	1.12
+++ include/opcode/arm.h	8 Mar 2008 17:13:06 -0000
@@ -64,6 +64,7 @@
 #define FPU_VFP_EXT_V2	 0x02000000	/* ARM10E VFPr1.	      */
 #define FPU_VFP_EXT_V3	 0x01000000	/* VFPv3 insns.	              */
 #define FPU_NEON_EXT_V1	 0x00800000	/* Neon (SIMD) insns.	      */
+#define FPU_VFP_EXT_D32  0x00400000	/* Registers D16-D31.	      */
 
 /* Architectures are the sum of the base and extensions.  The ARM ARM (rev E)
    defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
@@ -118,9 +119,10 @@
 #define FPU_VFP_V1xD	(FPU_VFP_EXT_V1xD | FPU_ENDIAN_PURE)
 #define FPU_VFP_V1	(FPU_VFP_V1xD | FPU_VFP_EXT_V1)
 #define FPU_VFP_V2	(FPU_VFP_V1 | FPU_VFP_EXT_V2)
-#define FPU_VFP_V3	(FPU_VFP_V2 | FPU_VFP_EXT_V3)
+#define FPU_VFP_V3D16	(FPU_VFP_V2 | FPU_VFP_EXT_V3)
+#define FPU_VFP_V3	(FPU_VFP_V3D16 | FPU_VFP_EXT_D32)
 #define FPU_VFP_HARD	(FPU_VFP_EXT_V1xD | FPU_VFP_EXT_V1 | FPU_VFP_EXT_V2 \
-                         | FPU_VFP_EXT_V3 | FPU_NEON_EXT_V1)
+                         | FPU_VFP_EXT_V3 | FPU_NEON_EXT_V1 | FPU_VFP_EXT_D32)
 #define FPU_FPA		(FPU_FPA_EXT_V1 | FPU_FPA_EXT_V2)
 
 /* Deprecated */
@@ -132,6 +134,7 @@
 #define FPU_ARCH_VFP_V1xD ARM_FEATURE (0, FPU_VFP_V1xD)
 #define FPU_ARCH_VFP_V1	  ARM_FEATURE (0, FPU_VFP_V1)
 #define FPU_ARCH_VFP_V2	  ARM_FEATURE (0, FPU_VFP_V2)
+#define FPU_ARCH_VFP_V3D16	ARM_FEATURE (0, FPU_VFP_V3D16)
 #define FPU_ARCH_VFP_V3	  ARM_FEATURE (0, FPU_VFP_V3)
 #define FPU_ARCH_NEON_V1  ARM_FEATURE (0, FPU_NEON_EXT_V1)
 #define FPU_ARCH_VFP_V3_PLUS_NEON_V1 \

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]