aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elfnn-riscv.c4
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/readelf.c21
-rw-r--r--gas/ChangeLog19
-rw-r--r--gas/config/tc-riscv.c197
-rw-r--r--gas/config/tc-riscv.h1
-rw-r--r--gas/doc/as.texinfo5
-rw-r--r--gas/doc/c-riscv.texi23
-rw-r--r--include/ChangeLog7
-rw-r--r--include/elf/riscv.h16
-rw-r--r--opcodes/ChangeLog5
-rw-r--r--opcodes/riscv-dis.c8
13 files changed, 186 insertions, 131 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f2b1707..259825d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,10 @@
2016-12-20 Andrew Waterman <andrew@sifive.com>
+ * elfnn-riscv.c (_bfd_riscv_elf_merge_private_bfd_data): Use
+ EF_RISCV_FLOAT_ABI_SOFT instead of EF_RISCV_SOFT_FLOAT.
+
+2016-12-20 Andrew Waterman <andrew@sifive.com>
+
* elfnn-riscv.c (bfd_riscv_get_max_alignment): Return bfd_vma
instead of unsigned int.
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index a9b0ac6..7f3ca72 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2597,8 +2597,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/ChangeLog b/binutils/ChangeLog
index 057e309..fd86ed5 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2016-12-20 Andrew Waterman <andrew@sifive.com>
+
+ * readelf.c (get_machine_flags): Use
+ EF_RISCV_FLOAT_ABI_{SOFT,SINGLE,DOBULE,QUAD) instead of
+ EF_RISCV_{SOFT,HARD}_FLOAT.
+
2016-12-14 Maciej W. Rozycki <macro@imgtec.com>
* testsuite/binutils-all/mips/mips-ase-1.d: New test.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index c8e9726..873a471 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3317,8 +3317,25 @@ 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/ChangeLog b/gas/ChangeLog
index 0e652b1..a603984 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,4 +1,23 @@
2016-12-20 Andrew Waterman <andrew@sifive.com>
+
+ * config/tc-riscv.h (xlen): Delete.
+ * config/tc-riscv.c (xlen): Make static.
+ (abi_xlen): New variable.
+ (options): Replace OPTION_{M32,M64,MSOFT_FLOAT,MHARD_FLOAT,MRVC}
+ with OPTION_MABI.
+ (md_longopts): Likewise.
+ (md_parse_option): Likewise.
+ (riscv_elf_final_processing): Likewise.
+ * doc/as.texinfo (Target RISC-V options): Likewise.
+ * doc/c-riscv.texi (OPTIONS): Likewise.
+ * config/tc-riscv.c (float_mode): Removed.
+ (float_abi): New type, specifies the floating-point ABI.
+ (riscv_set_abi): New function.
+ (riscv_add_subset): Only allow lower-case ISA names and require
+ them to start with "rv".
+ (riscv_after_parse_args): Likewise.
+
+2016-12-20 Andrew Waterman <andrew@sifive.com>
Kuan-Lin Chen <kuanlinchentw@gmail.com>
* config/tc-riscv.c (riscv_set_options): Add relax.
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index d011864..77c92cf 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -61,9 +61,10 @@ struct riscv_cl_insn
static const char default_arch[] = DEFAULT_ARCH;
-unsigned xlen = 0; /* width of an x-register */
+static unsigned xlen = 0; /* width of an x-register */
+static unsigned abi_xlen = 0; /* width of a pointer in the ABI */
-#define LOAD_ADDRESS_INSN (xlen == 64 ? "ld" : "lw")
+#define LOAD_ADDRESS_INSN (abi_xlen == 64 ? "ld" : "lw")
#define ADD32_INSN (xlen == 64 ? "addiw" : "addi")
static unsigned elf_flags = 0;
@@ -129,56 +130,49 @@ riscv_add_subset (const char *subset)
riscv_subsets = s;
}
-/* Set which ISA and extensions are available. Formally, ISA strings must
- begin with RV32 or RV64, but we allow the prefix to be omitted.
+/* Set which ISA and extensions are available. */
- FIXME: Version numbers are not supported yet. */
static void
-riscv_set_arch (const char *p)
+riscv_set_arch (const char *s)
{
- const char *all_subsets = "IMAFDC";
+ const char *all_subsets = "imafdc";
const char *extension = NULL;
- int rvc = 0;
- int i;
+ const char *p = s;
- if (strncasecmp (p, "RV32", 4) == 0)
+ if (strncmp (p, "rv32", 4) == 0)
{
xlen = 32;
p += 4;
}
- else if (strncasecmp (p, "RV64", 4) == 0)
+ else if (strncmp (p, "rv64", 4) == 0)
{
xlen = 64;
p += 4;
}
- else if (strncasecmp (p, "RV", 2) == 0)
- p += 2;
+ else
+ as_fatal ("-march=%s: ISA string must begin with rv32 or rv64", s);
- switch (TOUPPER(*p))
+ switch (*p)
{
- case 'I':
+ case 'i':
break;
- case 'G':
+ case 'g':
p++;
- /* Fall through. */
-
- case '\0':
- for (i = 0; all_subsets[i] != '\0'; i++)
+ for ( ; *all_subsets != 'c'; all_subsets++)
{
- const char subset[] = {all_subsets[i], '\0'};
+ const char subset[] = {*all_subsets, '\0'};
riscv_add_subset (subset);
}
break;
default:
- as_fatal ("`I' must be the first ISA subset name specified (got %c)",
- *p);
+ as_fatal ("-march=%s: first ISA subset must be `i' or `g'", s);
}
while (*p)
{
- if (TOUPPER(*p) == 'X')
+ if (*p == 'x')
{
char *subset = xstrdup (p), *q = subset;
@@ -187,8 +181,8 @@ riscv_set_arch (const char *p)
*q = '\0';
if (extension)
- as_fatal ("only one eXtension is supported (found %s and %s)",
- extension, subset);
+ as_fatal ("-march=%s: only one non-standard extension is supported"
+ " (found `%s' and `%s')", s, extension, subset);
extension = subset;
riscv_add_subset (subset);
p += strlen (subset);
@@ -200,24 +194,11 @@ riscv_set_arch (const char *p)
{
const char subset[] = {*p, 0};
riscv_add_subset (subset);
- if (TOUPPER(*p) == 'C')
- rvc = 1;
all_subsets++;
p++;
}
else
- as_fatal ("unsupported ISA subset %c", *p);
- }
-
- if (rvc)
- {
- /* Override -m[no-]rvc setting if C was explicitly listed. */
- riscv_set_rvc (TRUE);
- }
- else
- {
- /* Add RVC anyway. -m[no-]rvc toggles its availability. */
- riscv_add_subset ("C");
+ as_fatal ("-march=%s: unsupported ISA subset `%c'", s, *p);
}
}
@@ -604,8 +585,9 @@ void
md_begin (void)
{
int i = 0;
+ unsigned long mach = xlen == 64 ? bfd_mach_riscv64 : bfd_mach_riscv32;
- if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, 0))
+ if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach))
as_warn (_("Could not set architecture and machine"));
op_hash = hash_new ();
@@ -1717,72 +1699,46 @@ const char *md_shortopts = "O::g::G:";
enum options
{
- OPTION_M32 = OPTION_MD_BASE,
- OPTION_M64,
- OPTION_MARCH,
+ OPTION_MARCH = OPTION_MD_BASE,
OPTION_PIC,
OPTION_NO_PIC,
- OPTION_MSOFT_FLOAT,
- OPTION_MHARD_FLOAT,
- OPTION_MRVC,
- OPTION_MNO_RVC,
+ OPTION_MABI,
OPTION_END_OF_ENUM
};
struct option md_longopts[] =
{
- {"m32", no_argument, NULL, OPTION_M32},
- {"m64", no_argument, NULL, OPTION_M64},
{"march", required_argument, NULL, OPTION_MARCH},
{"fPIC", no_argument, NULL, OPTION_PIC},
{"fpic", no_argument, NULL, OPTION_PIC},
{"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},
+ {"mabi", required_argument, NULL, OPTION_MABI},
{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;
+
+static void
+riscv_set_abi (unsigned new_xlen, enum float_abi new_float_abi)
+{
+ abi_xlen = new_xlen;
+ float_abi = new_float_abi;
+}
int
md_parse_option (int c, const char *arg)
{
switch (c)
{
- case OPTION_MRVC:
- riscv_set_rvc (TRUE);
- break;
-
- case OPTION_MNO_RVC:
- riscv_set_rvc (FALSE);
- break;
-
- case OPTION_MSOFT_FLOAT:
- float_mode = FLOAT_MODE_SOFT;
- break;
-
- case OPTION_MHARD_FLOAT:
- float_mode = FLOAT_MODE_HARD;
- break;
-
- case OPTION_M32:
- xlen = 32;
- break;
-
- case OPTION_M64:
- xlen = 64;
- break;
-
case OPTION_MARCH:
riscv_set_arch (arg);
break;
@@ -1795,6 +1751,27 @@ md_parse_option (int c, const char *arg)
riscv_opts.pic = TRUE;
break;
+ case OPTION_MABI:
+ if (strcmp (arg, "ilp32") == 0)
+ riscv_set_abi (32, FLOAT_ABI_SOFT);
+ else if (strcmp (arg, "ilp32f") == 0)
+ riscv_set_abi (32, FLOAT_ABI_SINGLE);
+ else if (strcmp (arg, "ilp32d") == 0)
+ riscv_set_abi (32, FLOAT_ABI_DOUBLE);
+ else if (strcmp (arg, "ilp32q") == 0)
+ riscv_set_abi (32, FLOAT_ABI_QUAD);
+ else if (strcmp (arg, "lp64") == 0)
+ riscv_set_abi (64, FLOAT_ABI_SOFT);
+ else if (strcmp (arg, "lp64f") == 0)
+ riscv_set_abi (64, FLOAT_ABI_SINGLE);
+ else if (strcmp (arg, "lp64d") == 0)
+ riscv_set_abi (64, FLOAT_ABI_DOUBLE);
+ else if (strcmp (arg, "lp64q") == 0)
+ riscv_set_abi (64, FLOAT_ABI_QUAD);
+ else
+ return 0;
+ break;
+
default:
return 0;
}
@@ -1805,9 +1782,6 @@ md_parse_option (int c, const char *arg)
void
riscv_after_parse_args (void)
{
- if (riscv_subsets == NULL)
- riscv_set_arch ("RVIMAFD");
-
if (xlen == 0)
{
if (strcmp (default_arch, "riscv32") == 0)
@@ -1817,6 +1791,38 @@ riscv_after_parse_args (void)
else
as_bad ("unknown default architecture `%s'", default_arch);
}
+
+ if (riscv_subsets == NULL)
+ riscv_set_arch (xlen == 64 ? "rv64g" : "rv32g");
+
+ /* Add the RVC extension, regardless of -march, to support .option rvc. */
+ if (riscv_subset_supports ("c"))
+ riscv_set_rvc (TRUE);
+ else
+ riscv_add_subset ("c");
+
+ /* Infer ABI from ISA if not specified on command line. */
+ if (abi_xlen == 0)
+ abi_xlen = xlen;
+ else if (abi_xlen > xlen)
+ as_bad ("can't have %d-bit ABI on %d-bit ISA", abi_xlen, xlen);
+ else if (abi_xlen < xlen)
+ as_bad ("%d-bit ABI not yet supported on %d-bit ISA", abi_xlen, xlen);
+
+ 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
@@ -2449,24 +2455,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/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 32cf3ee..5e07fda 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -94,7 +94,6 @@ extern void riscv_cfi_frame_initial_instructions (void);
#define tc_regname_to_dw2regnum tc_riscv_regname_to_dw2regnum
extern int tc_riscv_regname_to_dw2regnum (char *);
-extern unsigned xlen;
#define DWARF2_DEFAULT_RETURN_COLUMN X_RA
/* Even on RV64, use 4-byte alignment, as F registers may be only 32 bits. */
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 2b00acc..4b14e08 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -514,9 +514,8 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
@ifset RISCV
@emph{Target RISC-V options:}
- [@b{-m32}|@b{-m64}]
- [@b{-mrvc}]
- [@b{-mhard-float}|@b{-msoft-float}]
+ [@b{-march}=@var{ISA}]
+ [@b{-mabi}=@var{ABI}]
@end ifset
@ifset S390
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index 8674ff2..25e4486 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -25,24 +25,17 @@ The following table lists all availiable RISC-V specific options
@c man begin OPTIONS
@table @gcctabopt
-@cindex @samp{-m32} option, RISC-V
-@cindex @samp{-m64} option, RISC-V
-@item -m32 | -m64
-Select the base ISA, either RV32 or RV64.
-
-@cindex @samp{-mrvc} option, RISC-V
-@item -mrvc
-Enables the C ISA subset for compressed instructions.
-
-@cindex @samp{-msoft-float} option, RISC-V
-@cindex @samp{-mhard-float} option, RISC-V
-@item -msoft-float | -mhard-float
-Select the floating-point ABI, hard-float has F registers while soft-float
-doesn't.
@cindex @samp{-march=ISA} option, RISC-V
@item -march=ISA
-Select the base isa, as specified by ISA. For example -march=RV32IMA.
+Select the base isa, as specified by ISA. For example -march=rv32ima.
+
+@cindex @samp{-mabi=ABI} option, RISC-V
+@item -mabi=ABI
+Selects the ABI, which is either "ilp32" or "lp64", optionally followed
+by "f", "d", or "q" to indicate single-precision, double-precision, or
+quad-precision floating-point calling convention, or none to indicate
+the soft-float calling convention.
@end table
@c man end
diff --git a/include/ChangeLog b/include/ChangeLog
index 51792be..ffefe65 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,4 +1,11 @@
2016-12-20 Andrew Waterman <andrew@sifive.com>
+
+ * elf/riscv.h (EF_RISCV_SOFT_FLOAT): Don't define.
+ (EF_RISCV_FLOAT_ABI, EF_RISCV_FLOAT_ABI_SOFT): Define.
+ (EF_RISCV_FLOAT_ABI_SINGLE, EF_RISCV_FLOAT_ABI_DOUBLE): Define.
+ (EF_RISCV_FLOAT_ABI_QUAD): Define.
+
+2016-12-20 Andrew Waterman <andrew@sifive.com>
Kuan-Lin Chen <kuanlinchentw@gmail.com>
* elf/riscv.h: Add R_RISCV_TPREL_I through R_RISCV_SET32.
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 4407611..5303bd9 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -94,7 +94,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 */
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index df466ef..92d2516 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,10 @@
2016-12-20 Andrew Waterman <andrew@sifive.com>
+ * riscv-dis.c (riscv_disassemble_insn): Default to the ELF's
+ XLEN when none is provided.
+
+2016-12-20 Andrew Waterman <andrew@sifive.com>
+
* riscv-opc.c: Formatting fixes.
2016-12-20 Alan Modra <amodra@gmail.com>
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 3b4e1e0..cb26350 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -406,8 +406,12 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
{
int xlen = 0;
- /* The incoming section might not always be complete. */
- if (info->section != NULL)
+ /* If XLEN is not known, get its value from the ELF class. */
+ if (info->mach == bfd_mach_riscv64)
+ xlen = 64;
+ else if (info->mach == bfd_mach_riscv32)
+ xlen = 32;
+ else if (info->section != NULL)
{
Elf_Internal_Ehdr *ehdr = elf_elfheader (info->section->owner);
xlen = ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? 64 : 32;