This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 1/2] Support GAS flag -mfloat-abi; remove .option soft/hard-float
- From: Palmer Dabbelt <palmer at dabbelt dot com>
- To: binutils at sourceware dot org
- Cc: Andrew Waterman <andrew at sifive dot com>
- Cc: Andrew Waterman <andrew at sifive dot com>
- Date: Tue, 1 Nov 2016 14:43:51 -0700
- Subject: [PATCH 1/2] Support GAS flag -mfloat-abi; remove .option soft/hard-float
- Authentication-results: sourceware.org; auth=none
- References: <1478036632-20017-1-git-send-email-palmer@dabbelt.com>
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