[PATCH 1/2] Support GAS flag -mfloat-abi; remove .option soft/hard-float

Palmer Dabbelt palmer@dabbelt.com
Tue Nov 1 21:44:00 GMT 2016


From: Andrew Waterman <andrew@sifive.com>

This changes the ELF flags and so breaks ABI compatibility.
---
 bfd/elfnn-riscv.c     |  4 +--
 binutils/readelf.c    | 20 ++++++++++++--
 gas/config/tc-riscv.c | 72 +++++++++++++++++++++++++--------------------------
 include/elf/riscv.h   | 16 ++++++++++--
 4 files changed, 69 insertions(+), 43 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index be1de22..6993d9e 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2577,8 +2577,8 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
       return TRUE;
     }
 
-  /* Disallow linking soft-float and hard-float.  */
-  if ((old_flags ^ new_flags) & EF_RISCV_SOFT_FLOAT)
+  /* Disallow linking different float ABIs.  */
+  if ((old_flags ^ new_flags) & EF_RISCV_FLOAT_ABI)
     {
       (*_bfd_error_handler)
 	(_("%B: can't link hard-float modules with soft-float modules"), ibfd);
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 114486c..583cc59 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3317,8 +3317,24 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
 	case EM_RISCV:
 	  if (e_flags & EF_RISCV_RVC)
 	    strcat (buf, ", RVC");
-	  if (e_flags & EF_RISCV_SOFT_FLOAT)
-	    strcat (buf, ", soft-float ABI");
+    switch (e_flags & EF_RISCV_FLOAT_ABI)
+      {
+      case EF_RISCV_FLOAT_ABI_SOFT:
+        strcat (buf, ", soft-float ABI");
+        break;
+
+      case EF_RISCV_FLOAT_ABI_SINGLE:
+        strcat (buf, ", single-float ABI");
+        break;
+
+      case EF_RISCV_FLOAT_ABI_DOUBLE:
+        strcat (buf, ", double-float ABI");
+        break;
+
+      case EF_RISCV_FLOAT_ABI_QUAD:
+        strcat (buf, ", quad-float ABI");
+        break;
+      }
 	  break;
 
 	case EM_SH:
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 592c95a..b9c349e 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1717,8 +1717,7 @@ enum options
   OPTION_MARCH,
   OPTION_PIC,
   OPTION_NO_PIC,
-  OPTION_MSOFT_FLOAT,
-  OPTION_MHARD_FLOAT,
+  OPTION_MFLOAT_ABI,
   OPTION_MRVC,
   OPTION_MNO_RVC,
   OPTION_END_OF_ENUM
@@ -1734,20 +1733,20 @@ struct option md_longopts[] =
   {"fno-pic", no_argument, NULL, OPTION_NO_PIC},
   {"mrvc", no_argument, NULL, OPTION_MRVC},
   {"mno-rvc", no_argument, NULL, OPTION_MNO_RVC},
-  {"msoft-float", no_argument, NULL, OPTION_MSOFT_FLOAT},
-  {"mhard-float", no_argument, NULL, OPTION_MHARD_FLOAT},
+  {"mfloat-abi", required_argument, NULL, OPTION_MFLOAT_ABI},
 
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof (md_longopts);
 
-enum float_mode
-{
-  FLOAT_MODE_DEFAULT,
-  FLOAT_MODE_SOFT,
-  FLOAT_MODE_HARD
+enum float_abi {
+  FLOAT_ABI_DEFAULT = -1,
+  FLOAT_ABI_SOFT,
+  FLOAT_ABI_SINGLE,
+  FLOAT_ABI_DOUBLE,
+  FLOAT_ABI_QUAD
 };
-static enum float_mode float_mode = FLOAT_MODE_DEFAULT;
+static enum float_abi float_abi = FLOAT_ABI_DEFAULT;
 
 int
 md_parse_option (int c, const char *arg)
@@ -1762,12 +1761,17 @@ md_parse_option (int c, const char *arg)
       riscv_set_rvc (FALSE);
       break;
 
-    case OPTION_MSOFT_FLOAT:
-      float_mode = FLOAT_MODE_SOFT;
-      break;
-
-    case OPTION_MHARD_FLOAT:
-      float_mode = FLOAT_MODE_HARD;
+    case OPTION_MFLOAT_ABI:
+      if (strcmp (arg, "soft") == 0)
+	float_abi = FLOAT_ABI_SOFT;
+      else if (strcmp (arg, "single") == 0)
+	float_abi = FLOAT_ABI_SINGLE;
+      else if (strcmp (arg, "double") == 0)
+	float_abi = FLOAT_ABI_DOUBLE;
+      else if (strcmp (arg, "quad") == 0)
+	float_abi = FLOAT_ABI_QUAD;
+      else
+	return 0;
       break;
 
     case OPTION_M32:
@@ -1812,6 +1816,21 @@ riscv_after_parse_args (void)
       else
 	as_bad ("unknown default architecture `%s'", default_arch);
     }
+
+  if (float_abi == FLOAT_ABI_DEFAULT)
+    {
+      struct riscv_subset *subset;
+
+      /* Assume soft-float unless D extension is present.  */
+      float_abi = FLOAT_ABI_SOFT;
+
+      for (subset = riscv_subsets; subset != NULL; subset = subset->next)
+	if (strcasecmp (subset->name, "D") == 0)
+	  float_abi = FLOAT_ABI_DOUBLE;
+    }
+
+  /* Insert float_abi into the EF_RISCV_FLOAT_ABI field of elf_flags.  */
+  elf_flags |= float_abi * (EF_RISCV_FLOAT_ABI & ~(EF_RISCV_FLOAT_ABI << 1));
 }
 
 long
@@ -1996,10 +2015,6 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
     riscv_opts.pic = TRUE;
   else if (strcmp (name, "nopic") == 0)
     riscv_opts.pic = FALSE;
-  else if (strcmp (name, "soft-float") == 0)
-    float_mode = FLOAT_MODE_SOFT;
-  else if (strcmp (name, "hard-float") == 0)
-    float_mode = FLOAT_MODE_HARD;
   else if (strcmp (name, "push") == 0)
     {
       struct riscv_option_stack *s;
@@ -2340,24 +2355,7 @@ tc_riscv_regname_to_dw2regnum (char *regname)
 void
 riscv_elf_final_processing (void)
 {
-  enum float_mode elf_float_mode = float_mode;
-
   elf_elfheader (stdoutput)->e_flags |= elf_flags;
-
-  if (elf_float_mode == FLOAT_MODE_DEFAULT)
-    {
-      struct riscv_subset *subset;
-
-      /* Assume soft-float unless D extension is present.  */
-      elf_float_mode = FLOAT_MODE_SOFT;
-
-      for (subset = riscv_subsets; subset != NULL; subset = subset->next)
-	if (strcasecmp (subset->name, "D") == 0)
-	  elf_float_mode = FLOAT_MODE_HARD;
-    }
-
-  if (elf_float_mode == FLOAT_MODE_SOFT)
-    elf_elfheader (stdoutput)->e_flags |= EF_RISCV_SOFT_FLOAT;
 }
 
 /* Parse the .sleb128 and .uleb128 pseudos.  Only allow constant expressions,
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 8415659..6995875 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -86,7 +86,19 @@ END_RELOC_NUMBERS (R_RISCV_max)
 /* File may contain compressed instructions.  */
 #define EF_RISCV_RVC 0x0001
 
-/* File uses the soft-float calling convention.  */
-#define EF_RISCV_SOFT_FLOAT 0x0002
+/* Which floating-point ABI a file uses.  */
+#define EF_RISCV_FLOAT_ABI 0x0006
+
+/* File uses the soft-float ABI.  */
+#define EF_RISCV_FLOAT_ABI_SOFT 0x0000
+
+/* File uses the single-float ABI.  */
+#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002
+
+/* File uses the double-float ABI.  */
+#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004
+
+/* File uses the quad-float ABI.  */
+#define EF_RISCV_FLOAT_ABI_QUAD 0x0006
 
 #endif /* _ELF_RISCV_H */
-- 
2.7.3



More information about the Binutils mailing list