public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs
       [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
                   ` (7 preceding siblings ...)
  2016-12-15  4:24 ` [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases Palmer Dabbelt
@ 2016-12-15  4:24 ` Palmer Dabbelt
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:24 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

sc is a misnomer, because they aren't inherently sc.
---
 opcodes/riscv-opc.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 9ea3b8a..3c732fd 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -343,17 +343,17 @@ const struct riscv_opcode riscv_opcodes[] =
 {"amomaxu.w.rl", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_RL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
 {"amomin.w.rl",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_RL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
 {"amominu.w.rl", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_RL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
-{"lr.w.sc",      "A",   "d,0(s)",    MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, 0 },
-{"sc.w.sc",      "A",   "d,t,0(s)",  MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, 0 },
-{"amoadd.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 },
-{"amoswap.w.sc", "A",   "d,t,0(s)",  MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 },
-{"amoand.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 },
-{"amoor.w.sc",   "A",   "d,t,0(s)",  MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 },
-{"amoxor.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 },
-{"amomax.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 },
-{"amomaxu.w.sc", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
-{"amomin.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
-{"amominu.w.sc", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
+{"lr.w.aqrl",    "A",   "d,0(s)",    MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, 0 },
+{"sc.w.aqrl",    "A",   "d,t,0(s)",  MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, 0 },
+{"amoadd.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 },
+{"amoswap.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 },
+{"amoand.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 },
+{"amoor.w.aqrl",   "A",   "d,t,0(s)",  MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 },
+{"amoxor.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 },
+{"amomax.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 },
+{"amomaxu.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
+{"amomin.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
+{"amominu.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
 {"lr.d",         "64A", "d,0(s)",    MATCH_LR_D, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
 {"sc.d",         "64A", "d,t,0(s)",  MATCH_SC_D, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
 {"amoadd.d",     "64A", "d,t,0(s)",  MATCH_AMOADD_D, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
@@ -387,17 +387,17 @@ const struct riscv_opcode riscv_opcodes[] =
 {"amomaxu.d.rl", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_RL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
 {"amomin.d.rl",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_RL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
 {"amominu.d.rl", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_RL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
-{"lr.d.sc",      "64A", "d,0(s)",    MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
-{"sc.d.sc",      "64A", "d,t,0(s)",  MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
-{"amoadd.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
-{"amoswap.d.sc", "64A", "d,t,0(s)",  MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 },
-{"amoand.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 },
-{"amoor.d.sc",   "64A", "d,t,0(s)",  MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 },
-{"amoxor.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 },
-{"amomax.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 },
-{"amomaxu.d.sc", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
-{"amomin.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
-{"amominu.d.sc", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
+{"lr.d.aqrl",    "64A", "d,0(s)",    MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
+{"sc.d.aqrl",    "64A", "d,t,0(s)",  MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
+{"amoadd.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
+{"amoswap.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 },
+{"amoand.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 },
+{"amoor.d.aqrl",   "64A", "d,t,0(s)",  MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 },
+{"amoxor.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 },
+{"amomax.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 },
+{"amomaxu.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
+{"amomin.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
+{"amominu.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
 
 /* Multiply/Divide instruction subset */
 {"mul",       "M",   "d,s,t",  MATCH_MUL, MASK_MUL, match_opcode, 0 },
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march
       [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
@ 2016-12-15  4:24 ` Palmer Dabbelt
  2016-12-15  4:24 ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:24 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

We've decided to standardize on two flags for RISC-V: "-march" sets the
target architecture (which determines which instructions can be
generated), and "-mabi" sets the target ABI.  We needed to rework this
because the old flag set didn't support soft-float or single-float ABIs,
and didn't support an x32-style ABI on RISC-V.

Additionally, we've changed the behavior of the -march flag: it's now a
lot stricter and only parses things we can actually understand.
Additionally, it's now lowercase-only: the rationale is that while the
RISC-V ISA manual specifies that ISA strings are case-insensitive, in
Linux-land things are usually case-sensitive.  Since this flag can be
used to determine library paths, we didn't want to bake some
case-insensitivity in there that would case trouble later.

This patch implements these two new flags and removes the old flags that
could conflict with these.  There wasn't a RISC-V release before, so we
want to just support a clean flag set.
---
 bfd/elfnn-riscv.c     |   4 +-
 binutils/readelf.c    |  21 +++++-
 gas/config/tc-riscv.c | 197 ++++++++++++++++++++++++--------------------------
 gas/config/tc-riscv.h |   1 -
 gas/doc/as.texinfo    |   5 +-
 gas/doc/c-riscv.texi  |  23 ++----
 include/elf/riscv.h   |  16 +++-
 opcodes/riscv-dis.c   |   8 +-
 8 files changed, 144 insertions(+), 131 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index b95267c..9c1c6ce 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/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/config/tc-riscv.c b/gas/config/tc-riscv.c
index a4a719f..58facff 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/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/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;
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 2/9] Formatting changes for RISC-V
       [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
                   ` (4 preceding siblings ...)
  2016-12-15  4:24 ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
@ 2016-12-15  4:24 ` Palmer Dabbelt
  2016-12-16 23:37   ` Mike Frysinger
  2016-12-15  4:24 ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:24 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

---
 bfd/elfnn-riscv.c     |  4 ++--
 bfd/elfxx-riscv.c     | 38 +++++++++++++++--------------------
 gas/config/tc-riscv.c | 55 ++++++++++++++++++++++++++-------------------------
 opcodes/riscv-opc.c   | 14 ++++++-------
 4 files changed, 52 insertions(+), 59 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 06ad4ff..749ac19 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -220,7 +220,7 @@ riscv_make_plt_entry (bfd_vma got, bfd_vma addr, uint32_t *entry)
      nop */
 
   entry[0] = RISCV_UTYPE (AUIPC, X_T3, RISCV_PCREL_HIGH_PART (got, addr));
-  entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART(got, addr));
+  entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART (got, addr));
   entry[2] = RISCV_ITYPE (JALR, X_T1, X_T3, 0);
   entry[3] = RISCV_NOP;
 }
@@ -2329,7 +2329,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && !(riscv_elf_hash_entry(h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
+      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
     {
       asection *sgot;
       asection *srela;
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index c1f28f7..0fb250d 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -63,7 +63,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_32",			/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
-	 0xffffffff,			/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   /* 64 bit relocation.  */
@@ -93,7 +93,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_RELATIVE",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
-	 0xffffffff,			/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   HOWTO (R_RISCV_COPY,			/* type */
@@ -106,8 +106,8 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_COPY",		/* name */
 	 FALSE,				/* partial_inplace */
-	 0x0,         			/* src_mask */
-	 0x0,		        	/* dst_mask */
+	 0,         			/* src_mask */
+	 0,		        	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   HOWTO (R_RISCV_JUMP_SLOT,		/* type */
@@ -120,8 +120,8 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_JUMP_SLOT",		/* name */
 	 FALSE,				/* partial_inplace */
-	 0x0,         			/* src_mask */
-	 0x0,		        	/* dst_mask */
+	 0,         			/* src_mask */
+	 0,		        	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   /* Dynamic TLS relocations.  */
@@ -135,7 +135,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPMOD32",	/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -149,7 +149,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPMOD64",	/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -163,7 +163,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPREL32",	/* name */
 	 TRUE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -177,7 +177,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPREL64",	/* name */
 	 TRUE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -191,7 +191,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_TPREL32",		/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -205,7 +205,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_TPREL64",		/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -238,9 +238,6 @@ static reloc_howto_type howto_table[] =
 	 TRUE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-					/* This needs complex overflow
-					   detection, because the upper 36
-					   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_JAL",			/* name */
 	 FALSE,				/* partial_inplace */
@@ -264,7 +261,7 @@ static reloc_howto_type howto_table[] =
 					/* dst_mask */
 	 TRUE),				/* pcrel_offset */
 
-  /* 32-bit PC-relative function call (AUIPC/JALR).  */
+  /* Like R_RISCV_CALL, but not locally binding.  */
   HOWTO (R_RISCV_CALL_PLT,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -460,7 +457,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* TLS LE thread pointer usage.  */
+  /* TLS LE thread pointer usage.  May be relaxed.  */
   HOWTO (R_RISCV_TPREL_ADD,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -665,9 +662,6 @@ static reloc_howto_type howto_table[] =
 	 TRUE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-					/* This needs complex overflow
-					   detection, because the upper 36
-					   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_RVC_JUMP",		/* name */
 	 FALSE,				/* partial_inplace */
@@ -690,7 +684,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_RVC_IMM (-1U),		/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* High 12 bits of 32-bit load or add.  */
+  /* GP-relative load.  */
   HOWTO (R_RISCV_GPREL_I,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -705,7 +699,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* High 12 bits of 32-bit store.  */
+  /* GP-relative store.  */
   HOWTO (R_RISCV_GPREL_S,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index b363867..d8a627d 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -28,6 +28,7 @@
 #include "itbl-ops.h"
 #include "dwarf2dbg.h"
 #include "dw2gencfi.h"
+#include "struc-symbol.h"
 
 #include "elf/riscv.h"
 #include "opcode/riscv.h"
@@ -511,29 +512,29 @@ validate_riscv_insn (const struct riscv_opcode *opc)
       case 'C': /* RVC */
 	switch (c = *p++)
 	  {
-	  case 'a': used_bits |= ENCODE_RVC_J_IMM(-1U); break;
+	  case 'a': used_bits |= ENCODE_RVC_J_IMM (-1U); break;
 	  case 'c': break; /* RS1, constrained to equal sp */
 	  case 'i': used_bits |= ENCODE_RVC_SIMM3(-1U); break;
-	  case 'j': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case 'k': used_bits |= ENCODE_RVC_LW_IMM(-1U); break;
-	  case 'l': used_bits |= ENCODE_RVC_LD_IMM(-1U); break;
-	  case 'm': used_bits |= ENCODE_RVC_LWSP_IMM(-1U); break;
-	  case 'n': used_bits |= ENCODE_RVC_LDSP_IMM(-1U); break;
-	  case 'p': used_bits |= ENCODE_RVC_B_IMM(-1U); break;
+	  case 'j': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case 'k': used_bits |= ENCODE_RVC_LW_IMM (-1U); break;
+	  case 'l': used_bits |= ENCODE_RVC_LD_IMM (-1U); break;
+	  case 'm': used_bits |= ENCODE_RVC_LWSP_IMM (-1U); break;
+	  case 'n': used_bits |= ENCODE_RVC_LDSP_IMM (-1U); break;
+	  case 'p': used_bits |= ENCODE_RVC_B_IMM (-1U); break;
 	  case 's': USE_BITS (OP_MASK_CRS1S, OP_SH_CRS1S); break;
 	  case 't': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
-	  case 'u': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case 'v': used_bits |= ENCODE_RVC_IMM(-1U); break;
+	  case 'u': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case 'v': used_bits |= ENCODE_RVC_IMM (-1U); break;
 	  case 'w': break; /* RS1S, constrained to equal RD */
 	  case 'x': break; /* RS2S, constrained to equal RD */
-	  case 'K': used_bits |= ENCODE_RVC_ADDI4SPN_IMM(-1U); break;
-	  case 'L': used_bits |= ENCODE_RVC_ADDI16SP_IMM(-1U); break;
-	  case 'M': used_bits |= ENCODE_RVC_SWSP_IMM(-1U); break;
-	  case 'N': used_bits |= ENCODE_RVC_SDSP_IMM(-1U); break;
+	  case 'K': used_bits |= ENCODE_RVC_ADDI4SPN_IMM (-1U); break;
+	  case 'L': used_bits |= ENCODE_RVC_ADDI16SP_IMM (-1U); break;
+	  case 'M': used_bits |= ENCODE_RVC_SWSP_IMM (-1U); break;
+	  case 'N': used_bits |= ENCODE_RVC_SDSP_IMM (-1U); break;
 	  case 'U': break; /* RS1, constrained to equal RD */
 	  case 'V': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
-	  case '<': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case '>': used_bits |= ENCODE_RVC_IMM(-1U); break;
+	  case '<': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case '>': used_bits |= ENCODE_RVC_IMM (-1U); break;
 	  case 'T': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
 	  case 'D': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
 	  default:
@@ -563,11 +564,11 @@ validate_riscv_insn (const struct riscv_opcode *opc)
       case 'P':	USE_BITS (OP_MASK_PRED,		OP_SH_PRED); break;
       case 'Q':	USE_BITS (OP_MASK_SUCC,		OP_SH_SUCC); break;
       case 'o':
-      case 'j': used_bits |= ENCODE_ITYPE_IMM(-1U); break;
-      case 'a':	used_bits |= ENCODE_UJTYPE_IMM(-1U); break;
-      case 'p':	used_bits |= ENCODE_SBTYPE_IMM(-1U); break;
-      case 'q':	used_bits |= ENCODE_STYPE_IMM(-1U); break;
-      case 'u':	used_bits |= ENCODE_UTYPE_IMM(-1U); break;
+      case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break;
+      case 'a':	used_bits |= ENCODE_UJTYPE_IMM (-1U); break;
+      case 'p':	used_bits |= ENCODE_SBTYPE_IMM (-1U); break;
+      case 'q':	used_bits |= ENCODE_STYPE_IMM (-1U); break;
+      case 'u':	used_bits |= ENCODE_UTYPE_IMM (-1U); break;
       case '[': break;
       case ']': break;
       case '0': break;
@@ -661,7 +662,7 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
     {
       reloc_howto_type *howto;
 
-      gas_assert(address_expr);
+      gas_assert (address_expr);
       if (reloc_type == BFD_RELOC_12_PCREL
 	  || reloc_type == BFD_RELOC_RISCV_JMP)
 	{
@@ -814,7 +815,7 @@ static symbolS *
 make_internal_label (void)
 {
   return (symbolS *) local_symbol_make (FAKE_LABEL_NAME, now_seg,
-					(valueT) frag_now_fix(), frag_now);
+					(valueT) frag_now_fix (), frag_now);
 }
 
 /* Load an entry from the GOT.  */
@@ -874,14 +875,14 @@ load_const (int reg, expressionS *ep)
       return;
     }
 
-  if (xlen > 32 && !IS_SEXT_32BIT_NUM(ep->X_add_number))
+  if (xlen > 32 && !IS_SEXT_32BIT_NUM (ep->X_add_number))
     {
       /* Reduce to a signed 32-bit constant using SLLI and ADDI.  */
       while (((upper.X_add_number >> shift) & 1) == 0)
 	shift++;
 
       upper.X_add_number = (int64_t) upper.X_add_number >> shift;
-      load_const(reg, &upper);
+      load_const (reg, &upper);
 
       macro_build (NULL, "slli", "d,s,>", reg, reg, shift);
       if (lower.X_add_number != 0)
@@ -1469,8 +1470,8 @@ rvc_lui:
 		  my_getExpression (imm_expr, s);
 		  check_absolute_expr (ip, imm_expr);
 		  if ((unsigned long) imm_expr->X_add_number > 0xfff)
-		    as_warn(_("Improper CSR address (%lu)"),
-			    (unsigned long) imm_expr->X_add_number);
+		    as_warn (_("Improper CSR address (%lu)"),
+			     (unsigned long) imm_expr->X_add_number);
 		  INSERT_OPERAND (CSR, *ip, imm_expr->X_add_number);
 		  imm_expr->X_op = O_absent;
 		  s = expr_end;
@@ -2242,7 +2243,7 @@ md_convert_frag_branch (fragS *fragp)
 	    goto done;
 
 	  default:
-	    abort();
+	    abort ();
 	}
     }
 
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 1d8d579..256e089 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -34,8 +34,7 @@ const char * const riscv_gpr_names_numeric[NGPR] =
   "x24",  "x25",  "x26",  "x27",  "x28",  "x29",  "x30",  "x31"
 };
 
-const char * const riscv_gpr_names_abi[NGPR] =
-{
+const char * const riscv_gpr_names_abi[NGPR] = {
   "zero", "ra", "sp",  "gp",  "tp", "t0",  "t1",  "t2",
   "s0",   "s1", "a0",  "a1",  "a2", "a3",  "a4",  "a5",
   "a6",   "a7", "s2",  "s3",  "s4", "s5",  "s6",  "s7",
@@ -50,8 +49,7 @@ const char * const riscv_fpr_names_numeric[NFPR] =
   "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31"
 };
 
-const char * const riscv_fpr_names_abi[NFPR] =
-{
+const char * const riscv_fpr_names_abi[NFPR] = {
   "ft0", "ft1", "ft2",  "ft3",  "ft4", "ft5", "ft6",  "ft7",
   "fs0", "fs1", "fa0",  "fa1",  "fa2", "fa3", "fa4",  "fa5",
   "fa6", "fa7", "fs2",  "fs3",  "fs4", "fs5", "fs6",  "fs7",
@@ -72,9 +70,9 @@ const char * const riscv_fpr_names_abi[NFPR] =
 #define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2)
 #define MASK_RD (OP_MASK_RD << OP_SH_RD)
 #define MASK_CRS2 (OP_MASK_CRS2 << OP_SH_CRS2)
-#define MASK_IMM ENCODE_ITYPE_IMM(-1U)
-#define MASK_RVC_IMM ENCODE_RVC_IMM(-1U)
-#define MASK_UIMM ENCODE_UTYPE_IMM(-1U)
+#define MASK_IMM ENCODE_ITYPE_IMM (-1U)
+#define MASK_RVC_IMM ENCODE_RVC_IMM (-1U)
+#define MASK_UIMM ENCODE_UTYPE_IMM (-1U)
 #define MASK_RM (OP_MASK_RM << OP_SH_RM)
 #define MASK_PRED (OP_MASK_PRED << OP_SH_PRED)
 #define MASK_SUCC (OP_MASK_SUCC << OP_SH_SUCC)
@@ -240,7 +238,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"or",        "I",   "d,s,t",  MATCH_OR, MASK_OR, match_opcode, 0 },
 {"or",        "I",   "d,s,j",  MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS },
 {"auipc",     "I",   "d,u",  MATCH_AUIPC, MASK_AUIPC, match_opcode, 0 },
-{"seqz",      "I",   "d,s",  MATCH_SLTIU | ENCODE_ITYPE_IMM(1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
+{"seqz",      "I",   "d,s",  MATCH_SLTIU | ENCODE_ITYPE_IMM (1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
 {"snez",      "I",   "d,t",  MATCH_SLTU, MASK_SLTU | MASK_RS1, match_opcode, INSN_ALIAS },
 {"sltz",      "I",   "d,s",  MATCH_SLT, MASK_SLT | MASK_RS2, match_opcode, INSN_ALIAS },
 {"sgtz",      "I",   "d,t",  MATCH_SLT, MASK_SLT | MASK_RS1, match_opcode, INSN_ALIAS },
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 3/9] Rework RISC-V relocations
       [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
                   ` (2 preceding siblings ...)
  2016-12-15  4:24 ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
@ 2016-12-15  4:24 ` Palmer Dabbelt
  2016-12-16 23:39   ` Mike Frysinger
  2016-12-15  4:24 ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:24 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

Before this commit we didn't cleanly support CFI directives because the
internal offsets used to get relaxed which broke them.  This patch
significantly reworks how we handle linker relaxations:

 * DWARF is now properly supported

 * There is a ".option norelax" to disable relaxations, for when users
   write assembly that can't be relaxed (if it's to be later patched up,
   for example).

 * There is an additional _RELAX relocation that specifies when previous
   relocations can be relaxed.

We're in the process of documenting the RISC-V ELF ABI, which will
include documentation of our relocations

  https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md

but we expect that this relocation set will remain ABI compatible in the
future (ie, it's safe to release).

Thanks to Kuan-Lin Chen for figuring out how to correctly relax the
debug info!
---
 bfd/bfd-in2.h         |   9 +++
 bfd/elfnn-riscv.c     |  93 ++++++++++++++++++----
 bfd/elfxx-riscv.c     | 128 ++++++++++++++++++++++++++++++
 bfd/libbfd.h          |   9 +++
 bfd/reloc.c           |  18 +++++
 gas/config/tc-riscv.c | 213 +++++++++++++++++++++++++++++++++++++-------------
 gas/config/tc-riscv.h |   7 +-
 include/elf/riscv.h   |   8 ++
 8 files changed, 416 insertions(+), 69 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 1c6b70f..b5ac178 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -4737,6 +4737,15 @@ number for the SBIC, SBIS, SBI and CBI instructions  */
   BFD_RELOC_RISCV_RVC_LUI,
   BFD_RELOC_RISCV_GPREL_I,
   BFD_RELOC_RISCV_GPREL_S,
+  BFD_RELOC_RISCV_TPREL_I,
+  BFD_RELOC_RISCV_TPREL_S,
+  BFD_RELOC_RISCV_RELAX,
+  BFD_RELOC_RISCV_CFA,
+  BFD_RELOC_RISCV_SUB6,
+  BFD_RELOC_RISCV_SET6,
+  BFD_RELOC_RISCV_SET8,
+  BFD_RELOC_RISCV_SET16,
+  BFD_RELOC_RISCV_SET32,
 
 /* Renesas RL78 Relocations.  */
   BFD_RELOC_RL78_NEG8,
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 749ac19..1ee55f8 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1493,6 +1493,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_LO12_I:
     case R_RISCV_GPREL_I:
     case R_RISCV_TPREL_LO12_I:
+    case R_RISCV_TPREL_I:
     case R_RISCV_PCREL_LO12_I:
       value = ENCODE_ITYPE_IMM (value);
       break;
@@ -1500,6 +1501,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_LO12_S:
     case R_RISCV_GPREL_S:
     case R_RISCV_TPREL_LO12_S:
+    case R_RISCV_TPREL_S:
     case R_RISCV_PCREL_LO12_S:
       value = ENCODE_STYPE_IMM (value);
       break;
@@ -1548,10 +1550,15 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_ADD16:
     case R_RISCV_ADD32:
     case R_RISCV_ADD64:
+    case R_RISCV_SUB6:
     case R_RISCV_SUB8:
     case R_RISCV_SUB16:
     case R_RISCV_SUB32:
     case R_RISCV_SUB64:
+    case R_RISCV_SET6:
+    case R_RISCV_SET8:
+    case R_RISCV_SET16:
+    case R_RISCV_SET32:
     case R_RISCV_TLS_DTPREL32:
     case R_RISCV_TLS_DTPREL64:
       break;
@@ -1817,6 +1824,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
       switch (r_type)
 	{
 	case R_RISCV_NONE:
+	case R_RISCV_RELAX:
 	case R_RISCV_TPREL_ADD:
 	case R_RISCV_COPY:
 	case R_RISCV_JUMP_SLOT:
@@ -1830,6 +1838,10 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_RVC_LUI:
 	case R_RISCV_LO12_I:
 	case R_RISCV_LO12_S:
+	case R_RISCV_SET6:
+	case R_RISCV_SET8:
+	case R_RISCV_SET16:
+	case R_RISCV_SET32:
 	  /* These require no special handling beyond perform_relocation.  */
 	  break;
 
@@ -1923,6 +1935,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  }
 	  break;
 
+	case R_RISCV_SUB6:
 	case R_RISCV_SUB8:
 	case R_RISCV_SUB16:
 	case R_RISCV_SUB32:
@@ -1953,6 +1966,11 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_TPREL_LO12_I:
 	case R_RISCV_TPREL_LO12_S:
 	  relocation = tpoff (info, relocation);
+	  break;
+
+	case R_RISCV_TPREL_I:
+	case R_RISCV_TPREL_S:
+	  relocation = tpoff (info, relocation);
 	  if (VALID_ITYPE_IMM (relocation + rel->r_addend))
 	    {
 	      /* We can use tp as the base register.  */
@@ -1961,6 +1979,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	      insn |= X_TP << OP_SH_RS1;
 	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
 	    }
+	  else
+	    r = bfd_reloc_overflow;
 	  break;
 
 	case R_RISCV_GPREL_I:
@@ -2668,6 +2688,11 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count)
   return TRUE;
 }
 
+typedef bfd_boolean (*relax_func_t) (bfd *, asection *, asection *,
+				     struct bfd_link_info *,
+				     Elf_Internal_Rela *,
+				     bfd_vma, bfd_vma, bfd_vma, bfd_boolean *);
+
 /* Relax AUIPC + JALR into JAL.  */
 
 static bfd_boolean
@@ -2675,7 +2700,8 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 		       struct bfd_link_info *link_info,
 		       Elf_Internal_Rela *rel,
 		       bfd_vma symval,
-		       unsigned int max_alignment,
+		       bfd_vma max_alignment,
+		       bfd_vma reserve_size ATTRIBUTE_UNUSED,
 		       bfd_boolean *again)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2758,6 +2784,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
 		      unsigned int max_alignment,
+		      bfd_vma reserve_size,
 		      bfd_boolean *again)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2773,8 +2800,10 @@ _bfd_riscv_relax_lui (bfd *abfd,
   /* Is the reference in range of x0 or gp?
      Valid gp range conservatively because of alignment issue.  */
   if (VALID_ITYPE_IMM (symval)
-      || (symval >= gp && VALID_ITYPE_IMM (symval - gp + max_alignment))
-      || (symval < gp && VALID_ITYPE_IMM (symval - gp - max_alignment)))
+      || (symval >= gp
+	  && VALID_ITYPE_IMM (symval - gp + max_alignment + reserve_size))
+      || (symval < gp
+	  && VALID_ITYPE_IMM (symval - gp - max_alignment - reserve_size)))
     {
       unsigned sym = ELFNN_R_SYM (rel->r_info);
       switch (ELFNN_R_TYPE (rel->r_info))
@@ -2832,20 +2861,35 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
 			 struct bfd_link_info *link_info,
 			 Elf_Internal_Rela *rel,
 			 bfd_vma symval,
-			 unsigned int max_alignment ATTRIBUTE_UNUSED,
+			 bfd_vma max_alignment ATTRIBUTE_UNUSED,
+			 bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			 bfd_boolean *again)
 {
   /* See if this symbol is in range of tp.  */
   if (RISCV_CONST_HIGH_PART (tpoff (link_info, symval)) != 0)
     return TRUE;
 
-  /* We can delete the unnecessary LUI and tp add.  The LO12 reloc will be
-     made directly tp-relative.  */
   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
-  rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
+  switch (ELFNN_R_TYPE (rel->r_info))
+    {
+    case R_RISCV_TPREL_LO12_I:
+      rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_I);
+      return TRUE;
 
-  *again = TRUE;
-  return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
+    case R_RISCV_TPREL_LO12_S:
+      rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_S);
+      return TRUE;
+
+    case R_RISCV_TPREL_HI20:
+    case R_RISCV_TPREL_ADD:
+      /* We can delete the unnecessary instruction and reloc.  */
+      rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
+      *again = TRUE;
+      return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
+
+    default:
+      abort ();
+    }
 }
 
 /* Implement R_RISCV_ALIGN by deleting excess alignment NOPs.  */
@@ -2857,6 +2901,7 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
 			unsigned int max_alignment ATTRIBUTE_UNUSED,
+			bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			bfd_boolean *again ATTRIBUTE_UNUSED)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2909,7 +2954,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
   Elf_Internal_Rela *relocs;
   bfd_boolean ret = FALSE;
   unsigned int i;
-  unsigned int max_alignment;
+  bfd_vma max_alignment, reserve_size = 0;
 
   *again = FALSE;
 
@@ -2935,7 +2980,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
     {
       asection *sym_sec;
       Elf_Internal_Rela *rel = relocs + i;
-      typeof (&_bfd_riscv_relax_call) relax_func = NULL;
+      relax_func_t relax_func;
       int type = ELFNN_R_TYPE (rel->r_info);
       bfd_vma symval;
 
@@ -2947,13 +2992,26 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 		   || type == R_RISCV_LO12_I
 		   || type == R_RISCV_LO12_S)
 	    relax_func = _bfd_riscv_relax_lui;
-	  else if (type == R_RISCV_TPREL_HI20 || type == R_RISCV_TPREL_ADD)
+	  else if (type == R_RISCV_TPREL_HI20
+		   || type == R_RISCV_TPREL_ADD
+		   || type == R_RISCV_TPREL_LO12_I
+		   || type == R_RISCV_TPREL_LO12_S)
 	    relax_func = _bfd_riscv_relax_tls_le;
+	  else
+	    continue;
+
+	  /* Only relax this reloc if it is paired with R_RISCV_RELAX.  */
+	  if (i == sec->reloc_count - 1
+	      || ELFNN_R_TYPE ((rel + 1)->r_info) != R_RISCV_RELAX
+	      || rel->r_offset != (rel + 1)->r_offset)
+	    continue;
+
+	  /* Skip over the R_RISCV_RELAX.  */
+	  i++;
 	}
       else if (type == R_RISCV_ALIGN)
 	relax_func = _bfd_riscv_relax_align;
-
-      if (!relax_func)
+      else
 	continue;
 
       data->relocs = relocs;
@@ -2978,6 +3036,8 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	  /* A local symbol.  */
 	  Elf_Internal_Sym *isym = ((Elf_Internal_Sym *) symtab_hdr->contents
 				    + ELFNN_R_SYM (rel->r_info));
+	  reserve_size = (isym->st_size - rel->r_addend) > isym->st_size
+	    ? 0 : isym->st_size - rel->r_addend;
 
 	  if (isym->st_shndx == SHN_UNDEF)
 	    sym_sec = sec, symval = sec_addr (sec) + rel->r_offset;
@@ -3011,13 +3071,16 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	  else
 	    symval = sec_addr (h->root.u.def.section) + h->root.u.def.value;
 
+	  if (h->type != STT_FUNC)
+	    reserve_size =
+	      (h->size - rel->r_addend) > h->size ? 0 : h->size - rel->r_addend;
 	  sym_sec = h->root.u.def.section;
 	}
 
       symval += rel->r_addend;
 
       if (!relax_func (abfd, sec, sym_sec, info, rel, symval,
-		       max_alignment, again))
+		       max_alignment, reserve_size, again))
 	goto fail;
     }
 
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 0fb250d..3d935cf 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -713,6 +713,126 @@ static reloc_howto_type howto_table[] =
 	 0,				/* src_mask */
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
+
+  /* TP-relative TLS LE load.  */
+  HOWTO (R_RISCV_TPREL_I,		/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TPREL_I",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* TP-relative TLS LE store.  */
+  HOWTO (R_RISCV_TPREL_S,		/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TPREL_S",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* The paired relocation may be relaxed.  */
+  HOWTO (R_RISCV_RELAX,			/* type */
+	 0,				/* rightshift */
+	 3,				/* size */
+	 0,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_RELAX",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 6-bit in-place addition, for local label subtraction.  */
+  HOWTO (R_RISCV_SUB6,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SUB6",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0x3f,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 6-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET6,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET6",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0x3f,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 8-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET8,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET8",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 16-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET16,			/* type */
+	 0,				/* rightshift */
+	 1,				/* size */
+	 16,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET16",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 32-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET32,			/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET32",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
 };
 
 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
@@ -766,6 +886,14 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
   { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
   { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
+  { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
+  { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
+  { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
+  { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
+  { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
+  { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
+  { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
+  { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
 };
 
 /* Given a BFD reloc type, return a howto structure.  */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 5ec3993..76bbd09 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2204,6 +2204,15 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RISCV_RVC_LUI",
   "BFD_RELOC_RISCV_GPREL_I",
   "BFD_RELOC_RISCV_GPREL_S",
+  "BFD_RELOC_RISCV_TPREL_I",
+  "BFD_RELOC_RISCV_TPREL_S",
+  "BFD_RELOC_RISCV_RELAX",
+  "BFD_RELOC_RISCV_CFA",
+  "BFD_RELOC_RISCV_SUB6",
+  "BFD_RELOC_RISCV_SET6",
+  "BFD_RELOC_RISCV_SET8",
+  "BFD_RELOC_RISCV_SET16",
+  "BFD_RELOC_RISCV_SET32",
   "BFD_RELOC_RL78_NEG8",
   "BFD_RELOC_RL78_NEG16",
   "BFD_RELOC_RL78_NEG24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 56cd79b..3c7b606 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5124,6 +5124,24 @@ ENUMX
   BFD_RELOC_RISCV_GPREL_I
 ENUMX
   BFD_RELOC_RISCV_GPREL_S
+ENUMX
+  BFD_RELOC_RISCV_TPREL_I
+ENUMX
+  BFD_RELOC_RISCV_TPREL_S
+ENUMX
+  BFD_RELOC_RISCV_RELAX
+ENUMX
+  BFD_RELOC_RISCV_CFA
+ENUMX
+  BFD_RELOC_RISCV_SUB6
+ENUMX
+  BFD_RELOC_RISCV_SET6
+ENUMX
+  BFD_RELOC_RISCV_SET8
+ENUMX
+  BFD_RELOC_RISCV_SET16
+ENUMX
+  BFD_RELOC_RISCV_SET32
 ENUMDOC
   RISC-V relocations.
 
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index d8a627d..a4a719f 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -74,12 +74,14 @@ struct riscv_set_options
 {
   int pic; /* Generate position-independent code.  */
   int rvc; /* Generate RVC code.  */
+  int relax; /* Emit relocs the linker is allowed to relax.  */
 };
 
 static struct riscv_set_options riscv_opts =
 {
   0,	/* pic */
   0,	/* rvc */
+  1,	/* relax */
 };
 
 static void
@@ -648,6 +650,28 @@ md_begin (void)
   record_alignment (text_section, riscv_opts.rvc ? 1 : 2);
 }
 
+static insn_t
+riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type, bfd_vma value)
+{
+  switch (reloc_type)
+    {
+    case BFD_RELOC_32:
+      return value;
+
+    case BFD_RELOC_RISCV_HI20:
+      return ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
+
+    case BFD_RELOC_RISCV_LO12_S:
+      return ENCODE_STYPE_IMM (value);
+
+    case BFD_RELOC_RISCV_LO12_I:
+      return ENCODE_ITYPE_IMM (value);
+
+    default:
+      abort ();
+    }
+}
+
 /* Output an instruction.  IP is the instruction information.
    ADDRESS_EXPR is an operand of the instruction to be used with
    RELOC_TYPE.  */
@@ -676,43 +700,22 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
 	  return;
 	}
       else if (address_expr->X_op == O_constant)
+	ip->insn_opcode |= riscv_apply_const_reloc (reloc_type,
+						    address_expr->X_add_number);
+      else
 	{
-	  switch (reloc_type)
-	    {
-	    case BFD_RELOC_32:
-	      ip->insn_opcode |= address_expr->X_add_number;
-	      goto append;
+	  howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
+	  if (howto == NULL)
+	    as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
 
-	    case BFD_RELOC_RISCV_HI20:
-	      {
-		insn_t imm = RISCV_CONST_HIGH_PART (address_expr->X_add_number);
-		ip->insn_opcode |= ENCODE_UTYPE_IMM (imm);
-		goto append;
-	      }
-
-	    case BFD_RELOC_RISCV_LO12_S:
-	      ip->insn_opcode |= ENCODE_STYPE_IMM (address_expr->X_add_number);
-	      goto append;
+	  ip->fixp = fix_new_exp (ip->frag, ip->where,
+				  bfd_get_reloc_size (howto),
+				  address_expr, FALSE, reloc_type);
 
-	    case BFD_RELOC_RISCV_LO12_I:
-	      ip->insn_opcode |= ENCODE_ITYPE_IMM (address_expr->X_add_number);
-	      goto append;
-
-	    default:
-	      break;
-	    }
+	  ip->fixp->fx_tcbit = riscv_opts.relax;
 	}
-
-	howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
-	if (howto == NULL)
-	  as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
-
-	ip->fixp = fix_new_exp (ip->frag, ip->where,
-				bfd_get_reloc_size (howto),
-				address_expr, FALSE, reloc_type);
     }
 
-append:
   add_fixed_insn (ip);
   install_insn (ip);
 }
@@ -1085,7 +1088,8 @@ parse_relocation (char **str, bfd_reloc_code_real_type *reloc,
 
 	/* Check whether the output BFD supports this relocation.
 	   If not, issue an error and fall back on something safe.  */
-	if (!bfd_reloc_type_lookup (stdoutput, percent_op->reloc))
+	if (*reloc != BFD_RELOC_UNUSED
+	    && !bfd_reloc_type_lookup (stdoutput, *reloc))
 	  {
 	    as_bad ("relocation %s isn't supported by the current ABI",
 		    percent_op->str);
@@ -1826,45 +1830,56 @@ md_pcrel_from (fixS *fixP)
 void
 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
+  unsigned int subtype;
   bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
+  bfd_boolean relaxable = FALSE;
 
   /* Remember value for tc_gen_reloc.  */
   fixP->fx_addnumber = *valP;
 
   switch (fixP->fx_r_type)
     {
-    case BFD_RELOC_RISCV_TLS_GOT_HI20:
-    case BFD_RELOC_RISCV_TLS_GD_HI20:
-    case BFD_RELOC_RISCV_TLS_DTPREL32:
-    case BFD_RELOC_RISCV_TLS_DTPREL64:
-    case BFD_RELOC_RISCV_TPREL_HI20:
-    case BFD_RELOC_RISCV_TPREL_LO12_I:
-    case BFD_RELOC_RISCV_TPREL_LO12_S:
-    case BFD_RELOC_RISCV_TPREL_ADD:
-      S_SET_THREAD_LOCAL (fixP->fx_addsy);
-      /* Fall through.  */
-
-    case BFD_RELOC_RISCV_GOT_HI20:
-    case BFD_RELOC_RISCV_PCREL_HI20:
     case BFD_RELOC_RISCV_HI20:
     case BFD_RELOC_RISCV_LO12_I:
     case BFD_RELOC_RISCV_LO12_S:
+      bfd_putl32 (riscv_apply_const_reloc (fixP->fx_r_type, *valP)
+		  | bfd_getl32 (buf), buf);
+      relaxable = TRUE;
+      break;
+
+    case BFD_RELOC_RISCV_GOT_HI20:
+    case BFD_RELOC_RISCV_PCREL_HI20:
     case BFD_RELOC_RISCV_ADD8:
     case BFD_RELOC_RISCV_ADD16:
     case BFD_RELOC_RISCV_ADD32:
     case BFD_RELOC_RISCV_ADD64:
+    case BFD_RELOC_RISCV_SUB6:
     case BFD_RELOC_RISCV_SUB8:
     case BFD_RELOC_RISCV_SUB16:
     case BFD_RELOC_RISCV_SUB32:
     case BFD_RELOC_RISCV_SUB64:
-      gas_assert (fixP->fx_addsy != NULL);
-      /* Nothing needed to do.  The value comes from the reloc entry.  */
+    case BFD_RELOC_RISCV_RELAX:
+      break;
+
+    case BFD_RELOC_RISCV_TPREL_HI20:
+    case BFD_RELOC_RISCV_TPREL_LO12_I:
+    case BFD_RELOC_RISCV_TPREL_LO12_S:
+    case BFD_RELOC_RISCV_TPREL_ADD:
+      relaxable = TRUE;
+      /* Fall through.  */
+
+    case BFD_RELOC_RISCV_TLS_GOT_HI20:
+    case BFD_RELOC_RISCV_TLS_GD_HI20:
+    case BFD_RELOC_RISCV_TLS_DTPREL32:
+    case BFD_RELOC_RISCV_TLS_DTPREL64:
+      S_SET_THREAD_LOCAL (fixP->fx_addsy);
       break;
 
     case BFD_RELOC_64:
     case BFD_RELOC_32:
     case BFD_RELOC_16:
     case BFD_RELOC_8:
+    case BFD_RELOC_RISCV_CFA:
       if (fixP->fx_addsy && fixP->fx_subsy)
 	{
 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
@@ -1895,6 +1910,49 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
 	      break;
 
+	    case BFD_RELOC_RISCV_CFA:
+	      /* Load the byte to get the subtype.  */
+	      subtype = bfd_get_8 (NULL, &fixP->fx_frag->fr_literal[fixP->fx_where]);
+	      switch (subtype)
+		{
+		case DW_CFA_advance_loc1:
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET8;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
+		  break;
+
+		case DW_CFA_advance_loc2:
+		  fixP->fx_size = 2;
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_size = 2;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET16;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
+		  break;
+
+		case DW_CFA_advance_loc4:
+		  fixP->fx_size = 4;
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_size = 4;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET32;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
+		  break;
+
+		default:
+		  if (subtype < 0x80 && (subtype & 0x40))
+		    {
+		      /* DW_CFA_advance_loc */
+		      fixP->fx_r_type = BFD_RELOC_RISCV_SET6;
+		      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB6;
+		    }
+		  else
+		    as_fatal (_("internal error: bad CFA value #%d"), subtype);
+		  break;
+		}
+	      break;
+
 	    default:
 	      /* This case is unreachable.  */
 	      abort ();
@@ -1954,10 +2012,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	}
       break;
 
-    case BFD_RELOC_RISCV_PCREL_LO12_S:
-    case BFD_RELOC_RISCV_PCREL_LO12_I:
     case BFD_RELOC_RISCV_CALL:
     case BFD_RELOC_RISCV_CALL_PLT:
+      relaxable = TRUE;
+      break;
+
+    case BFD_RELOC_RISCV_PCREL_LO12_S:
+    case BFD_RELOC_RISCV_PCREL_LO12_I:
     case BFD_RELOC_RISCV_ALIGN:
       break;
 
@@ -1966,8 +2027,54 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL)
 	as_fatal (_("internal error: bad relocation #%d"), fixP->fx_r_type);
     }
+
+  /* Add an R_RISCV_RELAX reloc if the reloc is relaxable.  */
+  if (relaxable && fixP->fx_tcbit && fixP->fx_addsy != NULL)
+    {
+      fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
+      fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL;
+      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELAX;
+    }
 }
 
+/* Because the value of .cfi_remember_state may changed after relaxation,
+   we insert a fix to relocate it again in link-time.  */
+
+void
+riscv_pre_output_hook (void)
+{
+  frchainS *frchP;
+  asection *s;
+
+  for (s = stdoutput->sections; s; s = s->next)
+    for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
+      {
+	fragS *fragP;
+
+	for (fragP = frchP->frch_root; fragP; fragP = fragP->fr_next)
+	  {
+	    if (fragP->fr_type == rs_cfa)
+	      {
+		fragS *loc4_frag;
+		expressionS exp;
+
+		symbolS *add_symbol = fragP->fr_symbol->sy_value.X_add_symbol;
+		symbolS *op_symbol = fragP->fr_symbol->sy_value.X_op_symbol;
+
+		exp.X_op = O_subtract;
+		exp.X_add_symbol = add_symbol;
+		exp.X_add_number = 0;
+		exp.X_op_symbol = op_symbol;
+
+		loc4_frag = (fragS *) fragP->fr_opcode;
+		fix_new_exp (loc4_frag, (int) fragP->fr_offset, 1, &exp, 0,
+			     BFD_RELOC_RISCV_CFA);
+	      }
+	  }
+      }
+}
+
+
 /* This structure is used to hold a stack of .option values.  */
 
 struct riscv_option_stack
@@ -1998,10 +2105,10 @@ 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, "relax") == 0)
+    riscv_opts.relax = TRUE;
+  else if (strcmp (name, "norelax") == 0)
+    riscv_opts.relax = FALSE;
   else if (strcmp (name, "push") == 0)
     {
       struct riscv_option_stack *s;
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index c2a11ce..32cf3ee 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -61,6 +61,9 @@ extern void riscv_after_parse_args (void);
 #define md_parse_long_option(arg) riscv_parse_long_option (arg)
 extern int riscv_parse_long_option (const char *);
 
+#define md_pre_output_hook riscv_pre_output_hook()
+extern void riscv_pre_output_hook (void);
+
 /* Let the linker resolve all the relocs due to relaxation.  */
 #define tc_fix_adjustable(fixp) 0
 #define md_allow_local_subtract(l,r,s) 0
@@ -93,7 +96,9 @@ extern int tc_riscv_regname_to_dw2regnum (char *);
 
 extern unsigned xlen;
 #define DWARF2_DEFAULT_RETURN_COLUMN X_RA
-#define DWARF2_CIE_DATA_ALIGNMENT (-(int) (xlen / 8))
+
+/* Even on RV64, use 4-byte alignment, as F registers may be only 32 bits.  */
+#define DWARF2_CIE_DATA_ALIGNMENT -4
 
 #define elf_tc_final_processing riscv_elf_final_processing
 extern void riscv_elf_final_processing (void);
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 8415659..4407611 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -79,6 +79,14 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   RELOC_NUMBER (R_RISCV_RVC_LUI, 46)
   RELOC_NUMBER (R_RISCV_GPREL_I, 47)
   RELOC_NUMBER (R_RISCV_GPREL_S, 48)
+  RELOC_NUMBER (R_RISCV_TPREL_I, 49)
+  RELOC_NUMBER (R_RISCV_TPREL_S, 50)
+  RELOC_NUMBER (R_RISCV_RELAX, 51)
+  RELOC_NUMBER (R_RISCV_SUB6, 52)
+  RELOC_NUMBER (R_RISCV_SET6, 53)
+  RELOC_NUMBER (R_RISCV_SET8, 54)
+  RELOC_NUMBER (R_RISCV_SET16, 55)
+  RELOC_NUMBER (R_RISCV_SET32, 56)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Processor specific flags for the ELF header e_flags field.  */
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 6/9] Don't define our own .p2align
       [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
                   ` (5 preceding siblings ...)
  2016-12-15  4:24 ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
@ 2016-12-15  4:24 ` Palmer Dabbelt
  2016-12-15  4:24 ` [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases Palmer Dabbelt
  2016-12-15  4:24 ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:24 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

---
 gas/config/tc-riscv.c | 96 ++++++++++++++++++++++++++++++---------------------
 gas/config/tc-riscv.h | 14 ++++++--
 2 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 58facff..38eafe0 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2185,63 +2185,82 @@ s_bss (int ignore ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
-/* Align to a given power of two.  */
-
 static void
-s_align (int bytes_p)
+riscv_make_nops (char *buf, bfd_vma bytes)
 {
-  int fill_value = 0, fill_value_specified = 0;
-  int min_text_alignment = riscv_opts.rvc ? 2 : 4;
-  int alignment = get_absolute_expression(), bytes;
+  bfd_vma i = 0;
 
-  if (bytes_p)
+  if (bytes % 4 == 2)
     {
-      bytes = alignment;
-      if (bytes < 1 || (bytes & (bytes-1)) != 0)
-	as_bad (_("alignment not a power of 2: %d"), bytes);
-      for (alignment = 0; bytes > 1; bytes >>= 1)
-	alignment++;
+      md_number_to_chars (buf, RVC_NOP, 2);
+      i += 2;
     }
 
-  bytes = 1 << alignment;
+  gas_assert ((bytes - i) % 4 == 0);
 
-  if (alignment < 0 || alignment > 31)
-    as_bad (_("unsatisfiable alignment: %d"), alignment);
+  for ( ; i < bytes; i += 4)
+    md_number_to_chars (buf + i, RISCV_NOP, 4);
+}
 
-  if (*input_line_pointer == ',')
-    {
-      ++input_line_pointer;
-      fill_value = get_absolute_expression ();
-      fill_value_specified = 1;
-    }
+/* Called from md_do_align.  Used to create an alignment frag in a
+   code section by emitting a worst-case NOP sequence that the linker
+   will later relax to the correct number of NOPs.  We can't compute
+   the correct alignment now because of other linker relaxations.  */
+
+bfd_boolean
+riscv_frag_align_code (int n)
+{
+  bfd_vma bytes = (bfd_vma)1 << n;
+  bfd_vma min_text_alignment = riscv_opts.rvc ? 2 : 4;
+
+  /* When not relaxing, riscv_handle_align handles code alignment.  */
+  if (!riscv_opts.relax)
+    return FALSE;
 
-  if (!fill_value_specified
-      && subseg_text_p (now_seg)
-      && bytes > min_text_alignment)
+  if (bytes > min_text_alignment)
     {
-      /* Emit the worst-case NOP string.  The linker will delete any
-	 unnecessary NOPs.  This allows us to support code alignment
-	 in spite of linker relaxations.  */
-      bfd_vma i, worst_case_bytes = bytes - min_text_alignment;
+      bfd_vma worst_case_bytes = bytes - min_text_alignment;
       char *nops = frag_more (worst_case_bytes);
-      for (i = 0; i < worst_case_bytes - 2; i += 4)
-	md_number_to_chars (nops + i, RISCV_NOP, 4);
-      if (i < worst_case_bytes)
-	md_number_to_chars (nops + i, RVC_NOP, 2);
-
       expressionS ex;
+
       ex.X_op = O_constant;
       ex.X_add_number = worst_case_bytes;
 
+      riscv_make_nops (nops, worst_case_bytes);
+
       fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
 		   &ex, FALSE, BFD_RELOC_RISCV_ALIGN);
     }
-  else if (alignment)
-    frag_align (alignment, fill_value, 0);
 
-  record_alignment (now_seg, alignment);
+  return TRUE;
+}
 
-  demand_empty_rest_of_line ();
+/* Implement HANDLE_ALIGN.  */
+
+void
+riscv_handle_align (fragS *fragP)
+{
+  switch (fragP->fr_type)
+    {
+    case rs_align_code:
+      /* When relaxing, riscv_frag_align_code handles code alignment.  */
+      if (!riscv_opts.relax)
+	{
+	  bfd_signed_vma count = fragP->fr_next->fr_address
+				 - fragP->fr_address - fragP->fr_fix;
+
+	  if (count <= 0)
+	    break;
+
+	  count &= MAX_MEM_FOR_RS_ALIGN_CODE;
+	  riscv_make_nops (fragP->fr_literal + fragP->fr_fix, count);
+	  fragP->fr_var = count;
+	}
+      break;
+
+    default:
+      break;
+    }
 }
 
 int
@@ -2488,9 +2507,6 @@ static const pseudo_typeS riscv_pseudo_table[] =
   {"dtprelword", s_dtprel, 4},
   {"dtpreldword", s_dtprel, 8},
   {"bss", s_bss, 0},
-  {"align", s_align, 0},
-  {"p2align", s_align, 0},
-  {"balign", s_align, 1},
   {"uleb128", s_riscv_leb128, 0},
   {"sleb128", s_riscv_leb128, 1},
 
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 5e07fda..5d6b83f 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -48,8 +48,18 @@ extern int riscv_relax_frag (asection *, struct frag *, long);
 #define md_undefined_symbol(name)	(0)
 #define md_operand(x)
 
-/* FIXME: it is unclear if this is used, or if it is even correct.  */
-#define MAX_MEM_FOR_RS_ALIGN_CODE  (1 + 2)
+extern bfd_boolean riscv_frag_align_code (int);
+#define md_do_align(N, FILL, LEN, MAX, LABEL)				\
+  if ((N) != 0 && !(FILL) && !need_pass_2 && subseg_text_p (now_seg))	\
+    {									\
+      if (riscv_frag_align_code (N))					\
+	goto LABEL;							\
+    }
+
+extern void riscv_handle_align (fragS *);
+#define HANDLE_ALIGN riscv_handle_align
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE 7
 
 /* The ISA of the target may change based on command-line arguments.  */
 #define TARGET_FORMAT riscv_target_format()
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases
       [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
                   ` (6 preceding siblings ...)
  2016-12-15  4:24 ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
@ 2016-12-15  4:24 ` Palmer Dabbelt
  2016-12-15  4:24 ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:24 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

This fixes https://github.com/riscv/riscv-binutils-gdb/issues/36.
---
 opcodes/riscv-opc.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 69fca09..9ea3b8a 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -264,12 +264,12 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fence",     "I",   "",  MATCH_FENCE | MASK_PRED | MASK_SUCC, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
 {"fence",     "I",   "P,Q",  MATCH_FENCE, MASK_FENCE | MASK_RD | MASK_RS1 | (MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 },
 {"fence.i",   "I",   "",  MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 },
-{"rdcycle",   "I",   "d",  MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, 0 },
-{"rdinstret", "I",   "d",  MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, 0 },
-{"rdtime",    "I",   "d",  MATCH_RDTIME, MASK_RDTIME, match_opcode, 0 },
-{"rdcycleh",  "32I", "d",  MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, 0 },
-{"rdinstreth","32I", "d",  MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, 0 },
-{"rdtimeh",   "32I", "d",  MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, 0 },
+{"rdcycle",   "I",   "d",  MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, INSN_ALIAS },
+{"rdinstret", "I",   "d",  MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, INSN_ALIAS },
+{"rdtime",    "I",   "d",  MATCH_RDTIME, MASK_RDTIME, match_opcode, INSN_ALIAS },
+{"rdcycleh",  "32I", "d",  MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, INSN_ALIAS },
+{"rdinstreth","32I", "d",  MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, INSN_ALIAS },
+{"rdtimeh",   "32I", "d",  MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, INSN_ALIAS },
 {"ecall",     "I",   "",    MATCH_SCALL, MASK_SCALL, match_opcode, 0 },
 {"scall",     "I",   "",    MATCH_SCALL, MASK_SCALL, match_opcode, 0 },
 {"xori",      "I",   "d,s,j",  MATCH_XORI, MASK_XORI, match_opcode, 0 },
@@ -592,25 +592,25 @@ const struct riscv_opcode riscv_opcodes[] =
 {"c.fsw",     "32C", "CD,Ck(Cs)",  MATCH_C_FSW, MASK_C_FSW, match_opcode, 0 },
 
 /* Supervisor instructions */
-{"csrr",      "I",   "d,E",  MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, 0 },
-{"csrwi",     "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, 0 },
-{"csrw",      "I",   "E,s",  MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, 0 },
-{"csrw",      "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, 0 },
-{"csrsi",     "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, 0 },
-{"csrs",      "I",   "E,s",  MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, 0 },
-{"csrs",      "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, 0 },
-{"csrci",     "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, 0 },
-{"csrc",      "I",   "E,s",  MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, 0 },
-{"csrc",      "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, 0 },
-{"csrrw",     "I",   "d,E,s",  MATCH_CSRRW, MASK_CSRRW, match_opcode, 0 },
-{"csrrw",     "I",   "d,E,Z",  MATCH_CSRRWI, MASK_CSRRWI, match_opcode, 0 },
-{"csrrs",     "I",   "d,E,s",  MATCH_CSRRS, MASK_CSRRS, match_opcode, 0 },
-{"csrrs",     "I",   "d,E,Z",  MATCH_CSRRSI, MASK_CSRRSI, match_opcode, 0 },
-{"csrrc",     "I",   "d,E,s",  MATCH_CSRRC, MASK_CSRRC, match_opcode, 0 },
-{"csrrc",     "I",   "d,E,Z",  MATCH_CSRRCI, MASK_CSRRCI, match_opcode, 0 },
+{"csrr",      "I",   "d,E",  MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, INSN_ALIAS },
+{"csrwi",     "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrsi",     "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrci",     "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrw",      "I",   "E,s",  MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrw",      "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrs",      "I",   "E,s",  MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrs",      "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrc",      "I",   "E,s",  MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrc",      "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
 {"csrrwi",    "I",   "d,E,Z",  MATCH_CSRRWI, MASK_CSRRWI, match_opcode, 0 },
 {"csrrsi",    "I",   "d,E,Z",  MATCH_CSRRSI, MASK_CSRRSI, match_opcode, 0 },
 {"csrrci",    "I",   "d,E,Z",  MATCH_CSRRCI, MASK_CSRRCI, match_opcode, 0 },
+{"csrrw",     "I",   "d,E,s",  MATCH_CSRRW, MASK_CSRRW, match_opcode, 0 },
+{"csrrw",     "I",   "d,E,Z",  MATCH_CSRRWI, MASK_CSRRWI, match_opcode, INSN_ALIAS },
+{"csrrs",     "I",   "d,E,s",  MATCH_CSRRS, MASK_CSRRS, match_opcode, 0 },
+{"csrrs",     "I",   "d,E,Z",  MATCH_CSRRSI, MASK_CSRRSI, match_opcode, INSN_ALIAS },
+{"csrrc",     "I",   "d,E,s",  MATCH_CSRRC, MASK_CSRRC, match_opcode, 0 },
+{"csrrc",     "I",   "d,E,Z",  MATCH_CSRRCI, MASK_CSRRCI, match_opcode, INSN_ALIAS },
 {"uret",      "I",   "",     MATCH_URET, MASK_URET, match_opcode, 0 },
 {"sret",      "I",   "",     MATCH_SRET, MASK_SRET, match_opcode, 0 },
 {"hret",      "I",   "",     MATCH_HRET, MASK_HRET, match_opcode, 0 },
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 1/9] Improve a LD error message when linking elf32 and elf64
       [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
  2016-12-15  4:24 ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
  2016-12-15  4:24 ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
@ 2016-12-15  4:24 ` Palmer Dabbelt
  2016-12-16 23:36   ` Mike Frysinger
  2016-12-15  4:24 ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:24 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman, Palmer Dabbelt

I recently ran into this error message and found it's not helpful: it
just tells me some temporary file can't be linked.  This slightly
improved one at least tells me it's because of an elf32/elf64 conflict.
---
 bfd/elfnn-riscv.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 4f11cf6..06ad4ff 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2561,8 +2561,9 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
     {
       (*_bfd_error_handler)
-	(_("%B: ABI is incompatible with that of the selected emulation"),
-	 ibfd);
+	(_("%B: ABI is incompatible with that of the selected emulation:\n"
+           "  target emulation '%s' does not match '%s'"),
+	 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
       return FALSE;
     }
 
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 7/9] Add canonical JALR assembly representation
       [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
  2016-12-15  4:24 ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
@ 2016-12-15  4:24 ` Palmer Dabbelt
  2016-12-15  4:24 ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:24 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

    jalr rd,offset(rs1)

rather than

    jalr rd,rs1,offset

This matches the format of other instructions.
---
 opcodes/riscv-opc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 256e089..69fca09 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -132,11 +132,14 @@ const struct riscv_opcode riscv_opcodes[] =
 {"ret",       "I",   "",  MATCH_JALR | (X_RA << OP_SH_RS1), MASK_JALR | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
 {"jr",        "C",   "d",  MATCH_C_JR, MASK_C_JR, match_rd_nonzero, INSN_ALIAS },
 {"jr",        "I",   "s",  MATCH_JALR, MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jr",        "I",   "o(s)",  MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jr",        "I",   "s,j",  MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "C",   "d",  MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, INSN_ALIAS },
 {"jalr",      "I",   "s",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jalr",      "I",   "o(s)",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "I",   "s,j",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "I",   "d,s",  MATCH_JALR, MASK_JALR | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jalr",      "I",   "d,o(s)",  MATCH_JALR, MASK_JALR, match_opcode, 0 },
 {"jalr",      "I",   "d,s,j",  MATCH_JALR, MASK_JALR, match_opcode, 0 },
 {"j",         "C",   "Ca",  MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS },
 {"j",         "I",   "a",  MATCH_JAL, MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS },
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 4/9] Fix an integer overflow in relocation handling
       [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
                   ` (3 preceding siblings ...)
  2016-12-15  4:24 ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
@ 2016-12-15  4:24 ` Palmer Dabbelt
  2016-12-15  4:24 ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:24 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

---
 bfd/elfnn-riscv.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 1ee55f8..b95267c 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2759,7 +2759,7 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 
 /* Traverse all output sections and return the max alignment.  */
 
-static unsigned int
+static bfd_vma
 _bfd_riscv_get_max_alignment (asection *sec)
 {
   unsigned int max_alignment_power = 0;
@@ -2771,7 +2771,7 @@ _bfd_riscv_get_max_alignment (asection *sec)
 	max_alignment_power = o->alignment_power;
     }
 
-  return 1 << max_alignment_power;
+  return (bfd_vma) 1 << max_alignment_power;
 }
 
 /* Relax non-PIC global variable references.  */
@@ -2783,7 +2783,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      struct bfd_link_info *link_info,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
-		      unsigned int max_alignment,
+		      bfd_vma max_alignment,
 		      bfd_vma reserve_size,
 		      bfd_boolean *again)
 {
@@ -2900,7 +2900,7 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
-			unsigned int max_alignment ATTRIBUTE_UNUSED,
+			bfd_vma max_alignment ATTRIBUTE_UNUSED,
 			bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			bfd_boolean *again ATTRIBUTE_UNUSED)
 {
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* RISC-V Fixes for 2.28
@ 2016-12-15  4:28 Palmer Dabbelt
  2016-12-16 19:47 ` Palmer Dabbelt
  0 siblings, 1 reply; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-15  4:28 UTC (permalink / raw)
  To: binutils; +Cc: Andrew Waterman

Sorry we've been quite for a bit: we were really trying to get things right
before submitting another patch set, because once our port is released we're
going to have to support it forever.  We've spent considerable time on the
RISC-V mailing lists trying to get all this right, and we're pretty sure this
patch set provides a good base for the first release of the RISC-V binutils
port.  The goal here is to only have one "flag day", and for that to happen
before there are any releases of any core RISC-V toolchain ports (with binutils
being the first).

In this patch set, there are some small changes and some big changes.  The big
changes are:

 * A reworking of the RISC-V relocations.  With these commits we can properly
   support CFI from GCC (thanks to Kuan-Lin Chen for finding a great
   implementation of this), rather than relying on some GCC hacks to avoid
   linker deficiencies.

 * Changes to the ELF ABI flags and gas/ld arguments.  These changes are
   necessary to allow us to properly support multiple ABIs, including both
   ARM-style floating point (ie, orthogonalizing the calling convention from
   code generation) and x32-style ABIs (though we don't have ilp32-on-rv64g
   working yet).

There's also a few smaller changes, but those are all well described within the
patch set -- they're mostly specific bug fixes or responses to code reviews, so
they're pretty self-contained.  There's a few code review fixes, some
formatting changes, and a handful of assembly fixes.

We really don't want to base our support on what's currently upstream, since
it's not quite extensible enough to maintain reasonable ABI compatibility
forever.  I understand this is a big patch set to be dropping right before a
release is meant to be branched off, so I'll dedicate 100% of my time to
getting all this ready-to-merge until it's good.

[PATCH 1/9] Improve a LD error message when linking elf32 and elf64
[PATCH 2/9] Formatting changes for RISC-V
[PATCH 3/9] Rework RISC-V relocations
[PATCH 4/9] Fix an integer overflow in relocation handling
[PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and
[PATCH 6/9] Don't define our own .p2align
[PATCH 7/9] Add canonical JALR assembly representation
[PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases
[PATCH 9/9] Correct assembler mnemonic for aqrl AMOs

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: RISC-V Fixes for 2.28
  2016-12-15  4:28 RISC-V Fixes for 2.28 Palmer Dabbelt
@ 2016-12-16 19:47 ` Palmer Dabbelt
  2016-12-16 23:11   ` Alan Modra
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
  0 siblings, 2 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-16 19:47 UTC (permalink / raw)
  To: binutils, nickc; +Cc: Andrew Waterman, kuanlinchentw

On Wed, 14 Dec 2016 20:27:55 PST (-0800), Palmer Dabbelt wrote:
> Sorry we've been quite for a bit: we were really trying to get things right
> before submitting another patch set, because once our port is released we're
> going to have to support it forever.  We've spent considerable time on the
> RISC-V mailing lists trying to get all this right, and we're pretty sure this
> patch set provides a good base for the first release of the RISC-V binutils
> port.  The goal here is to only have one "flag day", and for that to happen
> before there are any releases of any core RISC-V toolchain ports (with binutils
> being the first).
>
> In this patch set, there are some small changes and some big changes.  The big
> changes are:
>
>  * A reworking of the RISC-V relocations.  With these commits we can properly
>    support CFI from GCC (thanks to Kuan-Lin Chen for finding a great
>    implementation of this), rather than relying on some GCC hacks to avoid
>    linker deficiencies.
>
>  * Changes to the ELF ABI flags and gas/ld arguments.  These changes are
>    necessary to allow us to properly support multiple ABIs, including both
>    ARM-style floating point (ie, orthogonalizing the calling convention from
>    code generation) and x32-style ABIs (though we don't have ilp32-on-rv64g
>    working yet).
>
> There's also a few smaller changes, but those are all well described within the
> patch set -- they're mostly specific bug fixes or responses to code reviews, so
> they're pretty self-contained.  There's a few code review fixes, some
> formatting changes, and a handful of assembly fixes.
>
> We really don't want to base our support on what's currently upstream, since
> it's not quite extensible enough to maintain reasonable ABI compatibility
> forever.  I understand this is a big patch set to be dropping right before a
> release is meant to be branched off, so I'll dedicate 100% of my time to
> getting all this ready-to-merge until it's good.
>
> [PATCH 1/9] Improve a LD error message when linking elf32 and elf64
> [PATCH 2/9] Formatting changes for RISC-V
> [PATCH 3/9] Rework RISC-V relocations
> [PATCH 4/9] Fix an integer overflow in relocation handling
> [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and
> [PATCH 6/9] Don't define our own .p2align
> [PATCH 7/9] Add canonical JALR assembly representation
> [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases
> [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs

I know this is a big patch set to just blast out to the mailing list and expect
comments on in a day, but since there's a bit of time pressure due to the
upcoming release I'd like to check to see if anyone is still looking at this.
If not, here's the relevant ChangeLog entries:

gas/ChangeLog:

2016-12-16  Andrew Waterman <andrew@sifive.com>
	    Kuan-Lin Chen <kuanlinchentw@gmail.com>
	    Palmer Dabbelt <palmer@dabbelt.com>

	* Properly relax debug info, so GCC can emit CFI directives.
	* Add ".option {no,}relax", to turn on/off relaxations.
	* Change -march to require lower-case ISA strings.
	* Use -mabi instead of -m32/-m64 and -mfloat-abi=*.
	* Properly support .align and friends.
	* Disassemble jal/jalr correctly.
	* Disassemble CSR instructions correctly under -Mno-aliases.
	* Correct aqrl AMO mnemonic.

bfd/ChangeLog:

2016-12-16  Andrew Waterman <andrew@sifive.com>
	    Kuan-Lin Chen <kuanlinchentw@gmail.com>
	    Palmer Dabbelt <palmer@dabbelt.com>

	* Fix an integer overflow when in relocation handling.
	* Properly relax debug info, so GCC can emit CFI directives.
	* Add a _RELAX relocation, to conditionally control relaxation.

Thanks!

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: RISC-V Fixes for 2.28
  2016-12-16 19:47 ` Palmer Dabbelt
@ 2016-12-16 23:11   ` Alan Modra
  2016-12-18  6:40     ` Palmer Dabbelt
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
  1 sibling, 1 reply; 57+ messages in thread
From: Alan Modra @ 2016-12-16 23:11 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils, nickc, Andrew Waterman, kuanlinchentw

On Fri, Dec 16, 2016 at 11:47:17AM -0800, Palmer Dabbelt wrote:
> If not, here's the relevant ChangeLog entries:
> 
> gas/ChangeLog:
> 
> 2016-12-16  Andrew Waterman <andrew@sifive.com>
> 	    Kuan-Lin Chen <kuanlinchentw@gmail.com>
> 	    Palmer Dabbelt <palmer@dabbelt.com>
> 
> 	* Properly relax debug info, so GCC can emit CFI directives.
> 	* Add ".option {no,}relax", to turn on/off relaxations.
> 	* Change -march to require lower-case ISA strings.
> 	* Use -mabi instead of -m32/-m64 and -mfloat-abi=*.
> 	* Properly support .align and friends.
> 	* Disassemble jal/jalr correctly.
> 	* Disassemble CSR instructions correctly under -Mno-aliases.
> 	* Correct aqrl AMO mnemonic.
> 
> bfd/ChangeLog:
> 
> 2016-12-16  Andrew Waterman <andrew@sifive.com>
> 	    Kuan-Lin Chen <kuanlinchentw@gmail.com>
> 	    Palmer Dabbelt <palmer@dabbelt.com>
> 
> 	* Fix an integer overflow when in relocation handling.
> 	* Properly relax debug info, so GCC can emit CFI directives.
> 	* Add a _RELAX relocation, to conditionally control relaxation.

These are not proper ChangeLog entries.  See
https://www.gnu.org/prep/standards/html_node/Change-Log-Concepts.html
and following pages.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 1/9] Improve a LD error message when linking elf32 and elf64
  2016-12-15  4:24 ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
@ 2016-12-16 23:36   ` Mike Frysinger
  2016-12-18  6:40     ` Palmer Dabbelt
  0 siblings, 1 reply; 57+ messages in thread
From: Mike Frysinger @ 2016-12-16 23:36 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils, Andrew Waterman

[-- Attachment #1: Type: text/plain, Size: 152 bytes --]

On 14 Dec 2016 20:23, Palmer Dabbelt wrote:
> +           "  target emulation '%s' does not match '%s'"),

typically instead of '%s', we use `%s'
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 2/9] Formatting changes for RISC-V
  2016-12-15  4:24 ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
@ 2016-12-16 23:37   ` Mike Frysinger
  2016-12-18  6:39     ` Palmer Dabbelt
  0 siblings, 1 reply; 57+ messages in thread
From: Mike Frysinger @ 2016-12-16 23:37 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils, Andrew Waterman

[-- Attachment #1: Type: text/plain, Size: 145 bytes --]

On 14 Dec 2016 20:23, Palmer Dabbelt wrote:
> From: Andrew Waterman <andrew@sifive.com>
> 

this commit message needs an explanation
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 3/9] Rework RISC-V relocations
  2016-12-15  4:24 ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
@ 2016-12-16 23:39   ` Mike Frysinger
  2016-12-18  6:40     ` Palmer Dabbelt
  0 siblings, 1 reply; 57+ messages in thread
From: Mike Frysinger @ 2016-12-16 23:39 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils, Andrew Waterman

[-- Attachment #1: Type: text/plain, Size: 345 bytes --]

On 14 Dec 2016 20:23, Palmer Dabbelt wrote:
> +void
> +riscv_pre_output_hook (void)
> +{
> +  frchainS *frchP;

i don't think we normally use this naming style.  if the "p" means
pointer, then write it lower case instead of upper.

> +  asection *s;

should all of pointers in this func be const ?  at a glance, seems like
they should be.
-mike

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 2/9] Formatting changes for RISC-V
  2016-12-16 23:37   ` Mike Frysinger
@ 2016-12-18  6:39     ` Palmer Dabbelt
  0 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  6:39 UTC (permalink / raw)
  To: vapier; +Cc: binutils, Andrew Waterman

On Fri, 16 Dec 2016 15:37:07 PST (-0800), vapier@gentoo.org wrote:
> On 14 Dec 2016 20:23, Palmer Dabbelt wrote:
>> From: Andrew Waterman <andrew@sifive.com>
>>
>
> this commit message needs an explanation

OK.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: RISC-V Fixes for 2.28
  2016-12-16 23:11   ` Alan Modra
@ 2016-12-18  6:40     ` Palmer Dabbelt
  0 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  6:40 UTC (permalink / raw)
  To: amodra; +Cc: binutils, nickc, Andrew Waterman, kuanlinchentw

On Fri, 16 Dec 2016 15:11:26 PST (-0800), amodra@gmail.com wrote:
> On Fri, Dec 16, 2016 at 11:47:17AM -0800, Palmer Dabbelt wrote:
>> If not, here's the relevant ChangeLog entries:
>>
>> gas/ChangeLog:
>>
>> 2016-12-16  Andrew Waterman <andrew@sifive.com>
>> 	    Kuan-Lin Chen <kuanlinchentw@gmail.com>
>> 	    Palmer Dabbelt <palmer@dabbelt.com>
>>
>> 	* Properly relax debug info, so GCC can emit CFI directives.
>> 	* Add ".option {no,}relax", to turn on/off relaxations.
>> 	* Change -march to require lower-case ISA strings.
>> 	* Use -mabi instead of -m32/-m64 and -mfloat-abi=*.
>> 	* Properly support .align and friends.
>> 	* Disassemble jal/jalr correctly.
>> 	* Disassemble CSR instructions correctly under -Mno-aliases.
>> 	* Correct aqrl AMO mnemonic.
>>
>> bfd/ChangeLog:
>>
>> 2016-12-16  Andrew Waterman <andrew@sifive.com>
>> 	    Kuan-Lin Chen <kuanlinchentw@gmail.com>
>> 	    Palmer Dabbelt <palmer@dabbelt.com>
>>
>> 	* Fix an integer overflow when in relocation handling.
>> 	* Properly relax debug info, so GCC can emit CFI directives.
>> 	* Add a _RELAX relocation, to conditionally control relaxation.
>
> These are not proper ChangeLog entries.  See
> https://www.gnu.org/prep/standards/html_node/Change-Log-Concepts.html
> and following pages.

Sorry, I guess the first time I sent in a ChangeLog entry someone must have
manually massaged it.  I'll fix this in the future, I'm going to submit a v2 of
this patchset with all the feedback incorporated.

Thanks!

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 3/9] Rework RISC-V relocations
  2016-12-16 23:39   ` Mike Frysinger
@ 2016-12-18  6:40     ` Palmer Dabbelt
  0 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  6:40 UTC (permalink / raw)
  To: vapier; +Cc: binutils, Andrew Waterman

On Fri, 16 Dec 2016 15:39:48 PST (-0800), vapier@gentoo.org wrote:
> On 14 Dec 2016 20:23, Palmer Dabbelt wrote:
>> +void
>> +riscv_pre_output_hook (void)
>> +{
>> +  frchainS *frchP;
>
> i don't think we normally use this naming style.  if the "p" means
> pointer, then write it lower case instead of upper.

It looks like this code is mostly a copy of the xtensa code, but if it's odd
I'm OK just dropping the "P".  I've done that in the v2.

>> +  asection *s;
>
> should all of pointers in this func be const ?  at a glance, seems like
> they should be.

I don't see why not (and GCC doesn't seem to either :)).  Thanks for catching
this!

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 1/9] Improve a LD error message when linking elf32 and elf64
  2016-12-16 23:36   ` Mike Frysinger
@ 2016-12-18  6:40     ` Palmer Dabbelt
  0 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  6:40 UTC (permalink / raw)
  To: vapier; +Cc: binutils, Andrew Waterman

On Fri, 16 Dec 2016 15:36:26 PST (-0800), vapier@gentoo.org wrote:
> On 14 Dec 2016 20:23, Palmer Dabbelt wrote:
>> +           "  target emulation '%s' does not match '%s'"),
>
> typically instead of '%s', we use `%s'

OK, that's an easy fix.  I'm going to re-spin my patchset as a v2,
incorporating this (and all your other) feedback.

Thanks!

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
@ 2016-12-18  7:01     ` Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
                       ` (7 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

We've decided to standardize on two flags for RISC-V: "-march" sets the
target architecture (which determines which instructions can be
generated), and "-mabi" sets the target ABI.  We needed to rework this
because the old flag set didn't support soft-float or single-float ABIs,
and didn't support an x32-style ABI on RISC-V.

Additionally, we've changed the behavior of the -march flag: it's now a
lot stricter and only parses things we can actually understand.
Additionally, it's now lowercase-only: the rationale is that while the
RISC-V ISA manual specifies that ISA strings are case-insensitive, in
Linux-land things are usually case-sensitive.  Since this flag can be
used to determine library paths, we didn't want to bake some
case-insensitivity in there that would case trouble later.

This patch implements these two new flags and removes the old flags that
could conflict with these.  There wasn't a RISC-V release before, so we
want to just support a clean flag set.
---
 bfd/elfnn-riscv.c     |   4 +-
 binutils/readelf.c    |  21 +++++-
 gas/config/tc-riscv.c | 197 ++++++++++++++++++++++++--------------------------
 gas/config/tc-riscv.h |   1 -
 gas/doc/as.texinfo    |   5 +-
 gas/doc/c-riscv.texi  |  23 ++----
 include/elf/riscv.h   |  16 +++-
 opcodes/riscv-dis.c   |   8 +-
 8 files changed, 144 insertions(+), 131 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 461bce3..d76163e 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/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/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/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/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;
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 2/9] Formatting changes for RISC-V
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
@ 2016-12-18  7:01     ` Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
                       ` (6 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

This is a mixed bag of format changes:

 * Replacing constants with macros (0xffffffff with MINUS_ONE, for
   example).
 * Using 0 instead of 0x0 in the relocation table.
 * There were some missing spaces before parens, the spaces have been
   added.
 * A handful of comments are now more descriptive.
 * A bunch of whitespace-only changes, mostly alignment and brace
   newlines.
---
 bfd/elfnn-riscv.c     |  4 ++--
 bfd/elfxx-riscv.c     | 38 +++++++++++++++--------------------
 gas/config/tc-riscv.c | 55 ++++++++++++++++++++++++++-------------------------
 opcodes/riscv-opc.c   | 14 ++++++-------
 4 files changed, 52 insertions(+), 59 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 88d5d66..e18bd71 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -220,7 +220,7 @@ riscv_make_plt_entry (bfd_vma got, bfd_vma addr, uint32_t *entry)
      nop */
 
   entry[0] = RISCV_UTYPE (AUIPC, X_T3, RISCV_PCREL_HIGH_PART (got, addr));
-  entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART(got, addr));
+  entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART (got, addr));
   entry[2] = RISCV_ITYPE (JALR, X_T1, X_T3, 0);
   entry[3] = RISCV_NOP;
 }
@@ -2329,7 +2329,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && !(riscv_elf_hash_entry(h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
+      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
     {
       asection *sgot;
       asection *srela;
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index c1f28f7..0fb250d 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -63,7 +63,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_32",			/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
-	 0xffffffff,			/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   /* 64 bit relocation.  */
@@ -93,7 +93,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_RELATIVE",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
-	 0xffffffff,			/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   HOWTO (R_RISCV_COPY,			/* type */
@@ -106,8 +106,8 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_COPY",		/* name */
 	 FALSE,				/* partial_inplace */
-	 0x0,         			/* src_mask */
-	 0x0,		        	/* dst_mask */
+	 0,         			/* src_mask */
+	 0,		        	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   HOWTO (R_RISCV_JUMP_SLOT,		/* type */
@@ -120,8 +120,8 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_JUMP_SLOT",		/* name */
 	 FALSE,				/* partial_inplace */
-	 0x0,         			/* src_mask */
-	 0x0,		        	/* dst_mask */
+	 0,         			/* src_mask */
+	 0,		        	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   /* Dynamic TLS relocations.  */
@@ -135,7 +135,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPMOD32",	/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -149,7 +149,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPMOD64",	/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -163,7 +163,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPREL32",	/* name */
 	 TRUE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -177,7 +177,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPREL64",	/* name */
 	 TRUE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -191,7 +191,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_TPREL32",		/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -205,7 +205,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_TPREL64",		/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -238,9 +238,6 @@ static reloc_howto_type howto_table[] =
 	 TRUE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-					/* This needs complex overflow
-					   detection, because the upper 36
-					   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_JAL",			/* name */
 	 FALSE,				/* partial_inplace */
@@ -264,7 +261,7 @@ static reloc_howto_type howto_table[] =
 					/* dst_mask */
 	 TRUE),				/* pcrel_offset */
 
-  /* 32-bit PC-relative function call (AUIPC/JALR).  */
+  /* Like R_RISCV_CALL, but not locally binding.  */
   HOWTO (R_RISCV_CALL_PLT,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -460,7 +457,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* TLS LE thread pointer usage.  */
+  /* TLS LE thread pointer usage.  May be relaxed.  */
   HOWTO (R_RISCV_TPREL_ADD,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -665,9 +662,6 @@ static reloc_howto_type howto_table[] =
 	 TRUE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-					/* This needs complex overflow
-					   detection, because the upper 36
-					   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_RVC_JUMP",		/* name */
 	 FALSE,				/* partial_inplace */
@@ -690,7 +684,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_RVC_IMM (-1U),		/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* High 12 bits of 32-bit load or add.  */
+  /* GP-relative load.  */
   HOWTO (R_RISCV_GPREL_I,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -705,7 +699,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* High 12 bits of 32-bit store.  */
+  /* GP-relative store.  */
   HOWTO (R_RISCV_GPREL_S,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index b363867..d8a627d 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -28,6 +28,7 @@
 #include "itbl-ops.h"
 #include "dwarf2dbg.h"
 #include "dw2gencfi.h"
+#include "struc-symbol.h"
 
 #include "elf/riscv.h"
 #include "opcode/riscv.h"
@@ -511,29 +512,29 @@ validate_riscv_insn (const struct riscv_opcode *opc)
       case 'C': /* RVC */
 	switch (c = *p++)
 	  {
-	  case 'a': used_bits |= ENCODE_RVC_J_IMM(-1U); break;
+	  case 'a': used_bits |= ENCODE_RVC_J_IMM (-1U); break;
 	  case 'c': break; /* RS1, constrained to equal sp */
 	  case 'i': used_bits |= ENCODE_RVC_SIMM3(-1U); break;
-	  case 'j': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case 'k': used_bits |= ENCODE_RVC_LW_IMM(-1U); break;
-	  case 'l': used_bits |= ENCODE_RVC_LD_IMM(-1U); break;
-	  case 'm': used_bits |= ENCODE_RVC_LWSP_IMM(-1U); break;
-	  case 'n': used_bits |= ENCODE_RVC_LDSP_IMM(-1U); break;
-	  case 'p': used_bits |= ENCODE_RVC_B_IMM(-1U); break;
+	  case 'j': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case 'k': used_bits |= ENCODE_RVC_LW_IMM (-1U); break;
+	  case 'l': used_bits |= ENCODE_RVC_LD_IMM (-1U); break;
+	  case 'm': used_bits |= ENCODE_RVC_LWSP_IMM (-1U); break;
+	  case 'n': used_bits |= ENCODE_RVC_LDSP_IMM (-1U); break;
+	  case 'p': used_bits |= ENCODE_RVC_B_IMM (-1U); break;
 	  case 's': USE_BITS (OP_MASK_CRS1S, OP_SH_CRS1S); break;
 	  case 't': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
-	  case 'u': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case 'v': used_bits |= ENCODE_RVC_IMM(-1U); break;
+	  case 'u': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case 'v': used_bits |= ENCODE_RVC_IMM (-1U); break;
 	  case 'w': break; /* RS1S, constrained to equal RD */
 	  case 'x': break; /* RS2S, constrained to equal RD */
-	  case 'K': used_bits |= ENCODE_RVC_ADDI4SPN_IMM(-1U); break;
-	  case 'L': used_bits |= ENCODE_RVC_ADDI16SP_IMM(-1U); break;
-	  case 'M': used_bits |= ENCODE_RVC_SWSP_IMM(-1U); break;
-	  case 'N': used_bits |= ENCODE_RVC_SDSP_IMM(-1U); break;
+	  case 'K': used_bits |= ENCODE_RVC_ADDI4SPN_IMM (-1U); break;
+	  case 'L': used_bits |= ENCODE_RVC_ADDI16SP_IMM (-1U); break;
+	  case 'M': used_bits |= ENCODE_RVC_SWSP_IMM (-1U); break;
+	  case 'N': used_bits |= ENCODE_RVC_SDSP_IMM (-1U); break;
 	  case 'U': break; /* RS1, constrained to equal RD */
 	  case 'V': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
-	  case '<': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case '>': used_bits |= ENCODE_RVC_IMM(-1U); break;
+	  case '<': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case '>': used_bits |= ENCODE_RVC_IMM (-1U); break;
 	  case 'T': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
 	  case 'D': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
 	  default:
@@ -563,11 +564,11 @@ validate_riscv_insn (const struct riscv_opcode *opc)
       case 'P':	USE_BITS (OP_MASK_PRED,		OP_SH_PRED); break;
       case 'Q':	USE_BITS (OP_MASK_SUCC,		OP_SH_SUCC); break;
       case 'o':
-      case 'j': used_bits |= ENCODE_ITYPE_IMM(-1U); break;
-      case 'a':	used_bits |= ENCODE_UJTYPE_IMM(-1U); break;
-      case 'p':	used_bits |= ENCODE_SBTYPE_IMM(-1U); break;
-      case 'q':	used_bits |= ENCODE_STYPE_IMM(-1U); break;
-      case 'u':	used_bits |= ENCODE_UTYPE_IMM(-1U); break;
+      case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break;
+      case 'a':	used_bits |= ENCODE_UJTYPE_IMM (-1U); break;
+      case 'p':	used_bits |= ENCODE_SBTYPE_IMM (-1U); break;
+      case 'q':	used_bits |= ENCODE_STYPE_IMM (-1U); break;
+      case 'u':	used_bits |= ENCODE_UTYPE_IMM (-1U); break;
       case '[': break;
       case ']': break;
       case '0': break;
@@ -661,7 +662,7 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
     {
       reloc_howto_type *howto;
 
-      gas_assert(address_expr);
+      gas_assert (address_expr);
       if (reloc_type == BFD_RELOC_12_PCREL
 	  || reloc_type == BFD_RELOC_RISCV_JMP)
 	{
@@ -814,7 +815,7 @@ static symbolS *
 make_internal_label (void)
 {
   return (symbolS *) local_symbol_make (FAKE_LABEL_NAME, now_seg,
-					(valueT) frag_now_fix(), frag_now);
+					(valueT) frag_now_fix (), frag_now);
 }
 
 /* Load an entry from the GOT.  */
@@ -874,14 +875,14 @@ load_const (int reg, expressionS *ep)
       return;
     }
 
-  if (xlen > 32 && !IS_SEXT_32BIT_NUM(ep->X_add_number))
+  if (xlen > 32 && !IS_SEXT_32BIT_NUM (ep->X_add_number))
     {
       /* Reduce to a signed 32-bit constant using SLLI and ADDI.  */
       while (((upper.X_add_number >> shift) & 1) == 0)
 	shift++;
 
       upper.X_add_number = (int64_t) upper.X_add_number >> shift;
-      load_const(reg, &upper);
+      load_const (reg, &upper);
 
       macro_build (NULL, "slli", "d,s,>", reg, reg, shift);
       if (lower.X_add_number != 0)
@@ -1469,8 +1470,8 @@ rvc_lui:
 		  my_getExpression (imm_expr, s);
 		  check_absolute_expr (ip, imm_expr);
 		  if ((unsigned long) imm_expr->X_add_number > 0xfff)
-		    as_warn(_("Improper CSR address (%lu)"),
-			    (unsigned long) imm_expr->X_add_number);
+		    as_warn (_("Improper CSR address (%lu)"),
+			     (unsigned long) imm_expr->X_add_number);
 		  INSERT_OPERAND (CSR, *ip, imm_expr->X_add_number);
 		  imm_expr->X_op = O_absent;
 		  s = expr_end;
@@ -2242,7 +2243,7 @@ md_convert_frag_branch (fragS *fragp)
 	    goto done;
 
 	  default:
-	    abort();
+	    abort ();
 	}
     }
 
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 1d8d579..256e089 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -34,8 +34,7 @@ const char * const riscv_gpr_names_numeric[NGPR] =
   "x24",  "x25",  "x26",  "x27",  "x28",  "x29",  "x30",  "x31"
 };
 
-const char * const riscv_gpr_names_abi[NGPR] =
-{
+const char * const riscv_gpr_names_abi[NGPR] = {
   "zero", "ra", "sp",  "gp",  "tp", "t0",  "t1",  "t2",
   "s0",   "s1", "a0",  "a1",  "a2", "a3",  "a4",  "a5",
   "a6",   "a7", "s2",  "s3",  "s4", "s5",  "s6",  "s7",
@@ -50,8 +49,7 @@ const char * const riscv_fpr_names_numeric[NFPR] =
   "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31"
 };
 
-const char * const riscv_fpr_names_abi[NFPR] =
-{
+const char * const riscv_fpr_names_abi[NFPR] = {
   "ft0", "ft1", "ft2",  "ft3",  "ft4", "ft5", "ft6",  "ft7",
   "fs0", "fs1", "fa0",  "fa1",  "fa2", "fa3", "fa4",  "fa5",
   "fa6", "fa7", "fs2",  "fs3",  "fs4", "fs5", "fs6",  "fs7",
@@ -72,9 +70,9 @@ const char * const riscv_fpr_names_abi[NFPR] =
 #define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2)
 #define MASK_RD (OP_MASK_RD << OP_SH_RD)
 #define MASK_CRS2 (OP_MASK_CRS2 << OP_SH_CRS2)
-#define MASK_IMM ENCODE_ITYPE_IMM(-1U)
-#define MASK_RVC_IMM ENCODE_RVC_IMM(-1U)
-#define MASK_UIMM ENCODE_UTYPE_IMM(-1U)
+#define MASK_IMM ENCODE_ITYPE_IMM (-1U)
+#define MASK_RVC_IMM ENCODE_RVC_IMM (-1U)
+#define MASK_UIMM ENCODE_UTYPE_IMM (-1U)
 #define MASK_RM (OP_MASK_RM << OP_SH_RM)
 #define MASK_PRED (OP_MASK_PRED << OP_SH_PRED)
 #define MASK_SUCC (OP_MASK_SUCC << OP_SH_SUCC)
@@ -240,7 +238,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"or",        "I",   "d,s,t",  MATCH_OR, MASK_OR, match_opcode, 0 },
 {"or",        "I",   "d,s,j",  MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS },
 {"auipc",     "I",   "d,u",  MATCH_AUIPC, MASK_AUIPC, match_opcode, 0 },
-{"seqz",      "I",   "d,s",  MATCH_SLTIU | ENCODE_ITYPE_IMM(1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
+{"seqz",      "I",   "d,s",  MATCH_SLTIU | ENCODE_ITYPE_IMM (1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
 {"snez",      "I",   "d,t",  MATCH_SLTU, MASK_SLTU | MASK_RS1, match_opcode, INSN_ALIAS },
 {"sltz",      "I",   "d,s",  MATCH_SLT, MASK_SLT | MASK_RS2, match_opcode, INSN_ALIAS },
 {"sgtz",      "I",   "d,t",  MATCH_SLT, MASK_SLT | MASK_RS1, match_opcode, INSN_ALIAS },
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 3/9] Rework RISC-V relocations
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
                       ` (6 preceding siblings ...)
  2016-12-18  7:01     ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
@ 2016-12-18  7:01     ` Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
  2016-12-19  0:26     ` RISC-V Fixes for 2.28 v2 Alan Modra
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

Before this commit we didn't cleanly support CFI directives because the
internal offsets used to get relaxed which broke them.  This patch
significantly reworks how we handle linker relaxations:

 * DWARF is now properly supported

 * There is a ".option norelax" to disable relaxations, for when users
   write assembly that can't be relaxed (if it's to be later patched up,
   for example).

 * There is an additional _RELAX relocation that specifies when previous
   relocations can be relaxed.

We're in the process of documenting the RISC-V ELF ABI, which will
include documentation of our relocations

  https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md

but we expect that this relocation set will remain ABI compatible in the
future (ie, it's safe to release).

Thanks to Kuan-Lin Chen for figuring out how to correctly relax the
debug info!
---
 bfd/bfd-in2.h         |   9 +++
 bfd/elfnn-riscv.c     |  93 ++++++++++++++++++----
 bfd/elfxx-riscv.c     | 128 ++++++++++++++++++++++++++++++
 bfd/libbfd.h          |   9 +++
 bfd/reloc.c           |  18 +++++
 gas/config/tc-riscv.c | 213 +++++++++++++++++++++++++++++++++++++-------------
 gas/config/tc-riscv.h |   7 +-
 include/elf/riscv.h   |   8 ++
 8 files changed, 416 insertions(+), 69 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 1c6b70f..b5ac178 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -4737,6 +4737,15 @@ number for the SBIC, SBIS, SBI and CBI instructions  */
   BFD_RELOC_RISCV_RVC_LUI,
   BFD_RELOC_RISCV_GPREL_I,
   BFD_RELOC_RISCV_GPREL_S,
+  BFD_RELOC_RISCV_TPREL_I,
+  BFD_RELOC_RISCV_TPREL_S,
+  BFD_RELOC_RISCV_RELAX,
+  BFD_RELOC_RISCV_CFA,
+  BFD_RELOC_RISCV_SUB6,
+  BFD_RELOC_RISCV_SET6,
+  BFD_RELOC_RISCV_SET8,
+  BFD_RELOC_RISCV_SET16,
+  BFD_RELOC_RISCV_SET32,
 
 /* Renesas RL78 Relocations.  */
   BFD_RELOC_RL78_NEG8,
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index e18bd71..5976118 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1493,6 +1493,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_LO12_I:
     case R_RISCV_GPREL_I:
     case R_RISCV_TPREL_LO12_I:
+    case R_RISCV_TPREL_I:
     case R_RISCV_PCREL_LO12_I:
       value = ENCODE_ITYPE_IMM (value);
       break;
@@ -1500,6 +1501,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_LO12_S:
     case R_RISCV_GPREL_S:
     case R_RISCV_TPREL_LO12_S:
+    case R_RISCV_TPREL_S:
     case R_RISCV_PCREL_LO12_S:
       value = ENCODE_STYPE_IMM (value);
       break;
@@ -1548,10 +1550,15 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_ADD16:
     case R_RISCV_ADD32:
     case R_RISCV_ADD64:
+    case R_RISCV_SUB6:
     case R_RISCV_SUB8:
     case R_RISCV_SUB16:
     case R_RISCV_SUB32:
     case R_RISCV_SUB64:
+    case R_RISCV_SET6:
+    case R_RISCV_SET8:
+    case R_RISCV_SET16:
+    case R_RISCV_SET32:
     case R_RISCV_TLS_DTPREL32:
     case R_RISCV_TLS_DTPREL64:
       break;
@@ -1817,6 +1824,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
       switch (r_type)
 	{
 	case R_RISCV_NONE:
+	case R_RISCV_RELAX:
 	case R_RISCV_TPREL_ADD:
 	case R_RISCV_COPY:
 	case R_RISCV_JUMP_SLOT:
@@ -1830,6 +1838,10 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_RVC_LUI:
 	case R_RISCV_LO12_I:
 	case R_RISCV_LO12_S:
+	case R_RISCV_SET6:
+	case R_RISCV_SET8:
+	case R_RISCV_SET16:
+	case R_RISCV_SET32:
 	  /* These require no special handling beyond perform_relocation.  */
 	  break;
 
@@ -1923,6 +1935,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  }
 	  break;
 
+	case R_RISCV_SUB6:
 	case R_RISCV_SUB8:
 	case R_RISCV_SUB16:
 	case R_RISCV_SUB32:
@@ -1953,6 +1966,11 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_TPREL_LO12_I:
 	case R_RISCV_TPREL_LO12_S:
 	  relocation = tpoff (info, relocation);
+	  break;
+
+	case R_RISCV_TPREL_I:
+	case R_RISCV_TPREL_S:
+	  relocation = tpoff (info, relocation);
 	  if (VALID_ITYPE_IMM (relocation + rel->r_addend))
 	    {
 	      /* We can use tp as the base register.  */
@@ -1961,6 +1979,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	      insn |= X_TP << OP_SH_RS1;
 	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
 	    }
+	  else
+	    r = bfd_reloc_overflow;
 	  break;
 
 	case R_RISCV_GPREL_I:
@@ -2668,6 +2688,11 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count)
   return TRUE;
 }
 
+typedef bfd_boolean (*relax_func_t) (bfd *, asection *, asection *,
+				     struct bfd_link_info *,
+				     Elf_Internal_Rela *,
+				     bfd_vma, bfd_vma, bfd_vma, bfd_boolean *);
+
 /* Relax AUIPC + JALR into JAL.  */
 
 static bfd_boolean
@@ -2675,7 +2700,8 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 		       struct bfd_link_info *link_info,
 		       Elf_Internal_Rela *rel,
 		       bfd_vma symval,
-		       unsigned int max_alignment,
+		       bfd_vma max_alignment,
+		       bfd_vma reserve_size ATTRIBUTE_UNUSED,
 		       bfd_boolean *again)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2758,6 +2784,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
 		      unsigned int max_alignment,
+		      bfd_vma reserve_size,
 		      bfd_boolean *again)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2773,8 +2800,10 @@ _bfd_riscv_relax_lui (bfd *abfd,
   /* Is the reference in range of x0 or gp?
      Valid gp range conservatively because of alignment issue.  */
   if (VALID_ITYPE_IMM (symval)
-      || (symval >= gp && VALID_ITYPE_IMM (symval - gp + max_alignment))
-      || (symval < gp && VALID_ITYPE_IMM (symval - gp - max_alignment)))
+      || (symval >= gp
+	  && VALID_ITYPE_IMM (symval - gp + max_alignment + reserve_size))
+      || (symval < gp
+	  && VALID_ITYPE_IMM (symval - gp - max_alignment - reserve_size)))
     {
       unsigned sym = ELFNN_R_SYM (rel->r_info);
       switch (ELFNN_R_TYPE (rel->r_info))
@@ -2832,20 +2861,35 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
 			 struct bfd_link_info *link_info,
 			 Elf_Internal_Rela *rel,
 			 bfd_vma symval,
-			 unsigned int max_alignment ATTRIBUTE_UNUSED,
+			 bfd_vma max_alignment ATTRIBUTE_UNUSED,
+			 bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			 bfd_boolean *again)
 {
   /* See if this symbol is in range of tp.  */
   if (RISCV_CONST_HIGH_PART (tpoff (link_info, symval)) != 0)
     return TRUE;
 
-  /* We can delete the unnecessary LUI and tp add.  The LO12 reloc will be
-     made directly tp-relative.  */
   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
-  rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
+  switch (ELFNN_R_TYPE (rel->r_info))
+    {
+    case R_RISCV_TPREL_LO12_I:
+      rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_I);
+      return TRUE;
 
-  *again = TRUE;
-  return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
+    case R_RISCV_TPREL_LO12_S:
+      rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_S);
+      return TRUE;
+
+    case R_RISCV_TPREL_HI20:
+    case R_RISCV_TPREL_ADD:
+      /* We can delete the unnecessary instruction and reloc.  */
+      rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
+      *again = TRUE;
+      return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
+
+    default:
+      abort ();
+    }
 }
 
 /* Implement R_RISCV_ALIGN by deleting excess alignment NOPs.  */
@@ -2857,6 +2901,7 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
 			unsigned int max_alignment ATTRIBUTE_UNUSED,
+			bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			bfd_boolean *again ATTRIBUTE_UNUSED)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2909,7 +2954,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
   Elf_Internal_Rela *relocs;
   bfd_boolean ret = FALSE;
   unsigned int i;
-  unsigned int max_alignment;
+  bfd_vma max_alignment, reserve_size = 0;
 
   *again = FALSE;
 
@@ -2935,7 +2980,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
     {
       asection *sym_sec;
       Elf_Internal_Rela *rel = relocs + i;
-      typeof (&_bfd_riscv_relax_call) relax_func = NULL;
+      relax_func_t relax_func;
       int type = ELFNN_R_TYPE (rel->r_info);
       bfd_vma symval;
 
@@ -2947,13 +2992,26 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 		   || type == R_RISCV_LO12_I
 		   || type == R_RISCV_LO12_S)
 	    relax_func = _bfd_riscv_relax_lui;
-	  else if (type == R_RISCV_TPREL_HI20 || type == R_RISCV_TPREL_ADD)
+	  else if (type == R_RISCV_TPREL_HI20
+		   || type == R_RISCV_TPREL_ADD
+		   || type == R_RISCV_TPREL_LO12_I
+		   || type == R_RISCV_TPREL_LO12_S)
 	    relax_func = _bfd_riscv_relax_tls_le;
+	  else
+	    continue;
+
+	  /* Only relax this reloc if it is paired with R_RISCV_RELAX.  */
+	  if (i == sec->reloc_count - 1
+	      || ELFNN_R_TYPE ((rel + 1)->r_info) != R_RISCV_RELAX
+	      || rel->r_offset != (rel + 1)->r_offset)
+	    continue;
+
+	  /* Skip over the R_RISCV_RELAX.  */
+	  i++;
 	}
       else if (type == R_RISCV_ALIGN)
 	relax_func = _bfd_riscv_relax_align;
-
-      if (!relax_func)
+      else
 	continue;
 
       data->relocs = relocs;
@@ -2978,6 +3036,8 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	  /* A local symbol.  */
 	  Elf_Internal_Sym *isym = ((Elf_Internal_Sym *) symtab_hdr->contents
 				    + ELFNN_R_SYM (rel->r_info));
+	  reserve_size = (isym->st_size - rel->r_addend) > isym->st_size
+	    ? 0 : isym->st_size - rel->r_addend;
 
 	  if (isym->st_shndx == SHN_UNDEF)
 	    sym_sec = sec, symval = sec_addr (sec) + rel->r_offset;
@@ -3011,13 +3071,16 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	  else
 	    symval = sec_addr (h->root.u.def.section) + h->root.u.def.value;
 
+	  if (h->type != STT_FUNC)
+	    reserve_size =
+	      (h->size - rel->r_addend) > h->size ? 0 : h->size - rel->r_addend;
 	  sym_sec = h->root.u.def.section;
 	}
 
       symval += rel->r_addend;
 
       if (!relax_func (abfd, sec, sym_sec, info, rel, symval,
-		       max_alignment, again))
+		       max_alignment, reserve_size, again))
 	goto fail;
     }
 
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 0fb250d..3d935cf 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -713,6 +713,126 @@ static reloc_howto_type howto_table[] =
 	 0,				/* src_mask */
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
+
+  /* TP-relative TLS LE load.  */
+  HOWTO (R_RISCV_TPREL_I,		/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TPREL_I",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* TP-relative TLS LE store.  */
+  HOWTO (R_RISCV_TPREL_S,		/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TPREL_S",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* The paired relocation may be relaxed.  */
+  HOWTO (R_RISCV_RELAX,			/* type */
+	 0,				/* rightshift */
+	 3,				/* size */
+	 0,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_RELAX",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 6-bit in-place addition, for local label subtraction.  */
+  HOWTO (R_RISCV_SUB6,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SUB6",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0x3f,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 6-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET6,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET6",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0x3f,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 8-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET8,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET8",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 16-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET16,			/* type */
+	 0,				/* rightshift */
+	 1,				/* size */
+	 16,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET16",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 32-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET32,			/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET32",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
 };
 
 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
@@ -766,6 +886,14 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
   { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
   { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
+  { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
+  { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
+  { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
+  { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
+  { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
+  { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
+  { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
+  { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
 };
 
 /* Given a BFD reloc type, return a howto structure.  */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 5ec3993..76bbd09 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2204,6 +2204,15 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RISCV_RVC_LUI",
   "BFD_RELOC_RISCV_GPREL_I",
   "BFD_RELOC_RISCV_GPREL_S",
+  "BFD_RELOC_RISCV_TPREL_I",
+  "BFD_RELOC_RISCV_TPREL_S",
+  "BFD_RELOC_RISCV_RELAX",
+  "BFD_RELOC_RISCV_CFA",
+  "BFD_RELOC_RISCV_SUB6",
+  "BFD_RELOC_RISCV_SET6",
+  "BFD_RELOC_RISCV_SET8",
+  "BFD_RELOC_RISCV_SET16",
+  "BFD_RELOC_RISCV_SET32",
   "BFD_RELOC_RL78_NEG8",
   "BFD_RELOC_RL78_NEG16",
   "BFD_RELOC_RL78_NEG24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 56cd79b..3c7b606 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5124,6 +5124,24 @@ ENUMX
   BFD_RELOC_RISCV_GPREL_I
 ENUMX
   BFD_RELOC_RISCV_GPREL_S
+ENUMX
+  BFD_RELOC_RISCV_TPREL_I
+ENUMX
+  BFD_RELOC_RISCV_TPREL_S
+ENUMX
+  BFD_RELOC_RISCV_RELAX
+ENUMX
+  BFD_RELOC_RISCV_CFA
+ENUMX
+  BFD_RELOC_RISCV_SUB6
+ENUMX
+  BFD_RELOC_RISCV_SET6
+ENUMX
+  BFD_RELOC_RISCV_SET8
+ENUMX
+  BFD_RELOC_RISCV_SET16
+ENUMX
+  BFD_RELOC_RISCV_SET32
 ENUMDOC
   RISC-V relocations.
 
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index d8a627d..d011864 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -74,12 +74,14 @@ struct riscv_set_options
 {
   int pic; /* Generate position-independent code.  */
   int rvc; /* Generate RVC code.  */
+  int relax; /* Emit relocs the linker is allowed to relax.  */
 };
 
 static struct riscv_set_options riscv_opts =
 {
   0,	/* pic */
   0,	/* rvc */
+  1,	/* relax */
 };
 
 static void
@@ -648,6 +650,28 @@ md_begin (void)
   record_alignment (text_section, riscv_opts.rvc ? 1 : 2);
 }
 
+static insn_t
+riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type, bfd_vma value)
+{
+  switch (reloc_type)
+    {
+    case BFD_RELOC_32:
+      return value;
+
+    case BFD_RELOC_RISCV_HI20:
+      return ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
+
+    case BFD_RELOC_RISCV_LO12_S:
+      return ENCODE_STYPE_IMM (value);
+
+    case BFD_RELOC_RISCV_LO12_I:
+      return ENCODE_ITYPE_IMM (value);
+
+    default:
+      abort ();
+    }
+}
+
 /* Output an instruction.  IP is the instruction information.
    ADDRESS_EXPR is an operand of the instruction to be used with
    RELOC_TYPE.  */
@@ -676,43 +700,22 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
 	  return;
 	}
       else if (address_expr->X_op == O_constant)
+	ip->insn_opcode |= riscv_apply_const_reloc (reloc_type,
+						    address_expr->X_add_number);
+      else
 	{
-	  switch (reloc_type)
-	    {
-	    case BFD_RELOC_32:
-	      ip->insn_opcode |= address_expr->X_add_number;
-	      goto append;
+	  howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
+	  if (howto == NULL)
+	    as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
 
-	    case BFD_RELOC_RISCV_HI20:
-	      {
-		insn_t imm = RISCV_CONST_HIGH_PART (address_expr->X_add_number);
-		ip->insn_opcode |= ENCODE_UTYPE_IMM (imm);
-		goto append;
-	      }
-
-	    case BFD_RELOC_RISCV_LO12_S:
-	      ip->insn_opcode |= ENCODE_STYPE_IMM (address_expr->X_add_number);
-	      goto append;
+	  ip->fixp = fix_new_exp (ip->frag, ip->where,
+				  bfd_get_reloc_size (howto),
+				  address_expr, FALSE, reloc_type);
 
-	    case BFD_RELOC_RISCV_LO12_I:
-	      ip->insn_opcode |= ENCODE_ITYPE_IMM (address_expr->X_add_number);
-	      goto append;
-
-	    default:
-	      break;
-	    }
+	  ip->fixp->fx_tcbit = riscv_opts.relax;
 	}
-
-	howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
-	if (howto == NULL)
-	  as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
-
-	ip->fixp = fix_new_exp (ip->frag, ip->where,
-				bfd_get_reloc_size (howto),
-				address_expr, FALSE, reloc_type);
     }
 
-append:
   add_fixed_insn (ip);
   install_insn (ip);
 }
@@ -1085,7 +1088,8 @@ parse_relocation (char **str, bfd_reloc_code_real_type *reloc,
 
 	/* Check whether the output BFD supports this relocation.
 	   If not, issue an error and fall back on something safe.  */
-	if (!bfd_reloc_type_lookup (stdoutput, percent_op->reloc))
+	if (*reloc != BFD_RELOC_UNUSED
+	    && !bfd_reloc_type_lookup (stdoutput, *reloc))
 	  {
 	    as_bad ("relocation %s isn't supported by the current ABI",
 		    percent_op->str);
@@ -1826,45 +1830,56 @@ md_pcrel_from (fixS *fixP)
 void
 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
+  unsigned int subtype;
   bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
+  bfd_boolean relaxable = FALSE;
 
   /* Remember value for tc_gen_reloc.  */
   fixP->fx_addnumber = *valP;
 
   switch (fixP->fx_r_type)
     {
-    case BFD_RELOC_RISCV_TLS_GOT_HI20:
-    case BFD_RELOC_RISCV_TLS_GD_HI20:
-    case BFD_RELOC_RISCV_TLS_DTPREL32:
-    case BFD_RELOC_RISCV_TLS_DTPREL64:
-    case BFD_RELOC_RISCV_TPREL_HI20:
-    case BFD_RELOC_RISCV_TPREL_LO12_I:
-    case BFD_RELOC_RISCV_TPREL_LO12_S:
-    case BFD_RELOC_RISCV_TPREL_ADD:
-      S_SET_THREAD_LOCAL (fixP->fx_addsy);
-      /* Fall through.  */
-
-    case BFD_RELOC_RISCV_GOT_HI20:
-    case BFD_RELOC_RISCV_PCREL_HI20:
     case BFD_RELOC_RISCV_HI20:
     case BFD_RELOC_RISCV_LO12_I:
     case BFD_RELOC_RISCV_LO12_S:
+      bfd_putl32 (riscv_apply_const_reloc (fixP->fx_r_type, *valP)
+		  | bfd_getl32 (buf), buf);
+      relaxable = TRUE;
+      break;
+
+    case BFD_RELOC_RISCV_GOT_HI20:
+    case BFD_RELOC_RISCV_PCREL_HI20:
     case BFD_RELOC_RISCV_ADD8:
     case BFD_RELOC_RISCV_ADD16:
     case BFD_RELOC_RISCV_ADD32:
     case BFD_RELOC_RISCV_ADD64:
+    case BFD_RELOC_RISCV_SUB6:
     case BFD_RELOC_RISCV_SUB8:
     case BFD_RELOC_RISCV_SUB16:
     case BFD_RELOC_RISCV_SUB32:
     case BFD_RELOC_RISCV_SUB64:
-      gas_assert (fixP->fx_addsy != NULL);
-      /* Nothing needed to do.  The value comes from the reloc entry.  */
+    case BFD_RELOC_RISCV_RELAX:
+      break;
+
+    case BFD_RELOC_RISCV_TPREL_HI20:
+    case BFD_RELOC_RISCV_TPREL_LO12_I:
+    case BFD_RELOC_RISCV_TPREL_LO12_S:
+    case BFD_RELOC_RISCV_TPREL_ADD:
+      relaxable = TRUE;
+      /* Fall through.  */
+
+    case BFD_RELOC_RISCV_TLS_GOT_HI20:
+    case BFD_RELOC_RISCV_TLS_GD_HI20:
+    case BFD_RELOC_RISCV_TLS_DTPREL32:
+    case BFD_RELOC_RISCV_TLS_DTPREL64:
+      S_SET_THREAD_LOCAL (fixP->fx_addsy);
       break;
 
     case BFD_RELOC_64:
     case BFD_RELOC_32:
     case BFD_RELOC_16:
     case BFD_RELOC_8:
+    case BFD_RELOC_RISCV_CFA:
       if (fixP->fx_addsy && fixP->fx_subsy)
 	{
 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
@@ -1895,6 +1910,49 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
 	      break;
 
+	    case BFD_RELOC_RISCV_CFA:
+	      /* Load the byte to get the subtype.  */
+	      subtype = bfd_get_8 (NULL, &fixP->fx_frag->fr_literal[fixP->fx_where]);
+	      switch (subtype)
+		{
+		case DW_CFA_advance_loc1:
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET8;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
+		  break;
+
+		case DW_CFA_advance_loc2:
+		  fixP->fx_size = 2;
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_size = 2;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET16;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
+		  break;
+
+		case DW_CFA_advance_loc4:
+		  fixP->fx_size = 4;
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_size = 4;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET32;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
+		  break;
+
+		default:
+		  if (subtype < 0x80 && (subtype & 0x40))
+		    {
+		      /* DW_CFA_advance_loc */
+		      fixP->fx_r_type = BFD_RELOC_RISCV_SET6;
+		      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB6;
+		    }
+		  else
+		    as_fatal (_("internal error: bad CFA value #%d"), subtype);
+		  break;
+		}
+	      break;
+
 	    default:
 	      /* This case is unreachable.  */
 	      abort ();
@@ -1954,10 +2012,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	}
       break;
 
-    case BFD_RELOC_RISCV_PCREL_LO12_S:
-    case BFD_RELOC_RISCV_PCREL_LO12_I:
     case BFD_RELOC_RISCV_CALL:
     case BFD_RELOC_RISCV_CALL_PLT:
+      relaxable = TRUE;
+      break;
+
+    case BFD_RELOC_RISCV_PCREL_LO12_S:
+    case BFD_RELOC_RISCV_PCREL_LO12_I:
     case BFD_RELOC_RISCV_ALIGN:
       break;
 
@@ -1966,8 +2027,54 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL)
 	as_fatal (_("internal error: bad relocation #%d"), fixP->fx_r_type);
     }
+
+  /* Add an R_RISCV_RELAX reloc if the reloc is relaxable.  */
+  if (relaxable && fixP->fx_tcbit && fixP->fx_addsy != NULL)
+    {
+      fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
+      fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL;
+      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELAX;
+    }
 }
 
+/* Because the value of .cfi_remember_state may changed after relaxation,
+   we insert a fix to relocate it again in link-time.  */
+
+void
+riscv_pre_output_hook (void)
+{
+  const frchainS *frch;
+  const asection *s;
+
+  for (s = stdoutput->sections; s; s = s->next)
+    for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next)
+      {
+	const fragS *frag;
+
+	for (frag = frch->frch_root; frag; frag = frag->fr_next)
+	  {
+	    if (frag->fr_type == rs_cfa)
+	      {
+		const fragS *loc4_frag;
+		expressionS exp;
+
+		symbolS *add_symbol = frag->fr_symbol->sy_value.X_add_symbol;
+		symbolS *op_symbol = frag->fr_symbol->sy_value.X_op_symbol;
+
+		exp.X_op = O_subtract;
+		exp.X_add_symbol = add_symbol;
+		exp.X_add_number = 0;
+		exp.X_op_symbol = op_symbol;
+
+		loc4_frag = (fragS *) frag->fr_opcode;
+		fix_new_exp (loc4_frag, (int) frag->fr_offset, 1, &exp, 0,
+			     BFD_RELOC_RISCV_CFA);
+	      }
+	  }
+      }
+}
+
+
 /* This structure is used to hold a stack of .option values.  */
 
 struct riscv_option_stack
@@ -1998,10 +2105,10 @@ 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, "relax") == 0)
+    riscv_opts.relax = TRUE;
+  else if (strcmp (name, "norelax") == 0)
+    riscv_opts.relax = FALSE;
   else if (strcmp (name, "push") == 0)
     {
       struct riscv_option_stack *s;
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index c2a11ce..32cf3ee 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -61,6 +61,9 @@ extern void riscv_after_parse_args (void);
 #define md_parse_long_option(arg) riscv_parse_long_option (arg)
 extern int riscv_parse_long_option (const char *);
 
+#define md_pre_output_hook riscv_pre_output_hook()
+extern void riscv_pre_output_hook (void);
+
 /* Let the linker resolve all the relocs due to relaxation.  */
 #define tc_fix_adjustable(fixp) 0
 #define md_allow_local_subtract(l,r,s) 0
@@ -93,7 +96,9 @@ extern int tc_riscv_regname_to_dw2regnum (char *);
 
 extern unsigned xlen;
 #define DWARF2_DEFAULT_RETURN_COLUMN X_RA
-#define DWARF2_CIE_DATA_ALIGNMENT (-(int) (xlen / 8))
+
+/* Even on RV64, use 4-byte alignment, as F registers may be only 32 bits.  */
+#define DWARF2_CIE_DATA_ALIGNMENT -4
 
 #define elf_tc_final_processing riscv_elf_final_processing
 extern void riscv_elf_final_processing (void);
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 8415659..4407611 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -79,6 +79,14 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   RELOC_NUMBER (R_RISCV_RVC_LUI, 46)
   RELOC_NUMBER (R_RISCV_GPREL_I, 47)
   RELOC_NUMBER (R_RISCV_GPREL_S, 48)
+  RELOC_NUMBER (R_RISCV_TPREL_I, 49)
+  RELOC_NUMBER (R_RISCV_TPREL_S, 50)
+  RELOC_NUMBER (R_RISCV_RELAX, 51)
+  RELOC_NUMBER (R_RISCV_SUB6, 52)
+  RELOC_NUMBER (R_RISCV_SET6, 53)
+  RELOC_NUMBER (R_RISCV_SET8, 54)
+  RELOC_NUMBER (R_RISCV_SET16, 55)
+  RELOC_NUMBER (R_RISCV_SET32, 56)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Processor specific flags for the ELF header e_flags field.  */
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
                       ` (4 preceding siblings ...)
  2016-12-18  7:01     ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
@ 2016-12-18  7:01     ` Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
                       ` (3 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

This fixes https://github.com/riscv/riscv-binutils-gdb/issues/36.
---
 opcodes/riscv-opc.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 69fca09..9ea3b8a 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -264,12 +264,12 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fence",     "I",   "",  MATCH_FENCE | MASK_PRED | MASK_SUCC, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
 {"fence",     "I",   "P,Q",  MATCH_FENCE, MASK_FENCE | MASK_RD | MASK_RS1 | (MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 },
 {"fence.i",   "I",   "",  MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 },
-{"rdcycle",   "I",   "d",  MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, 0 },
-{"rdinstret", "I",   "d",  MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, 0 },
-{"rdtime",    "I",   "d",  MATCH_RDTIME, MASK_RDTIME, match_opcode, 0 },
-{"rdcycleh",  "32I", "d",  MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, 0 },
-{"rdinstreth","32I", "d",  MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, 0 },
-{"rdtimeh",   "32I", "d",  MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, 0 },
+{"rdcycle",   "I",   "d",  MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, INSN_ALIAS },
+{"rdinstret", "I",   "d",  MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, INSN_ALIAS },
+{"rdtime",    "I",   "d",  MATCH_RDTIME, MASK_RDTIME, match_opcode, INSN_ALIAS },
+{"rdcycleh",  "32I", "d",  MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, INSN_ALIAS },
+{"rdinstreth","32I", "d",  MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, INSN_ALIAS },
+{"rdtimeh",   "32I", "d",  MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, INSN_ALIAS },
 {"ecall",     "I",   "",    MATCH_SCALL, MASK_SCALL, match_opcode, 0 },
 {"scall",     "I",   "",    MATCH_SCALL, MASK_SCALL, match_opcode, 0 },
 {"xori",      "I",   "d,s,j",  MATCH_XORI, MASK_XORI, match_opcode, 0 },
@@ -592,25 +592,25 @@ const struct riscv_opcode riscv_opcodes[] =
 {"c.fsw",     "32C", "CD,Ck(Cs)",  MATCH_C_FSW, MASK_C_FSW, match_opcode, 0 },
 
 /* Supervisor instructions */
-{"csrr",      "I",   "d,E",  MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, 0 },
-{"csrwi",     "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, 0 },
-{"csrw",      "I",   "E,s",  MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, 0 },
-{"csrw",      "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, 0 },
-{"csrsi",     "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, 0 },
-{"csrs",      "I",   "E,s",  MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, 0 },
-{"csrs",      "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, 0 },
-{"csrci",     "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, 0 },
-{"csrc",      "I",   "E,s",  MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, 0 },
-{"csrc",      "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, 0 },
-{"csrrw",     "I",   "d,E,s",  MATCH_CSRRW, MASK_CSRRW, match_opcode, 0 },
-{"csrrw",     "I",   "d,E,Z",  MATCH_CSRRWI, MASK_CSRRWI, match_opcode, 0 },
-{"csrrs",     "I",   "d,E,s",  MATCH_CSRRS, MASK_CSRRS, match_opcode, 0 },
-{"csrrs",     "I",   "d,E,Z",  MATCH_CSRRSI, MASK_CSRRSI, match_opcode, 0 },
-{"csrrc",     "I",   "d,E,s",  MATCH_CSRRC, MASK_CSRRC, match_opcode, 0 },
-{"csrrc",     "I",   "d,E,Z",  MATCH_CSRRCI, MASK_CSRRCI, match_opcode, 0 },
+{"csrr",      "I",   "d,E",  MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, INSN_ALIAS },
+{"csrwi",     "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrsi",     "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrci",     "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrw",      "I",   "E,s",  MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrw",      "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrs",      "I",   "E,s",  MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrs",      "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrc",      "I",   "E,s",  MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrc",      "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
 {"csrrwi",    "I",   "d,E,Z",  MATCH_CSRRWI, MASK_CSRRWI, match_opcode, 0 },
 {"csrrsi",    "I",   "d,E,Z",  MATCH_CSRRSI, MASK_CSRRSI, match_opcode, 0 },
 {"csrrci",    "I",   "d,E,Z",  MATCH_CSRRCI, MASK_CSRRCI, match_opcode, 0 },
+{"csrrw",     "I",   "d,E,s",  MATCH_CSRRW, MASK_CSRRW, match_opcode, 0 },
+{"csrrw",     "I",   "d,E,Z",  MATCH_CSRRWI, MASK_CSRRWI, match_opcode, INSN_ALIAS },
+{"csrrs",     "I",   "d,E,s",  MATCH_CSRRS, MASK_CSRRS, match_opcode, 0 },
+{"csrrs",     "I",   "d,E,Z",  MATCH_CSRRSI, MASK_CSRRSI, match_opcode, INSN_ALIAS },
+{"csrrc",     "I",   "d,E,s",  MATCH_CSRRC, MASK_CSRRC, match_opcode, 0 },
+{"csrrc",     "I",   "d,E,Z",  MATCH_CSRRCI, MASK_CSRRCI, match_opcode, INSN_ALIAS },
 {"uret",      "I",   "",     MATCH_URET, MASK_URET, match_opcode, 0 },
 {"sret",      "I",   "",     MATCH_SRET, MASK_SRET, match_opcode, 0 },
 {"hret",      "I",   "",     MATCH_HRET, MASK_HRET, match_opcode, 0 },
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 7/9] Add canonical JALR assembly representation
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
                       ` (7 preceding siblings ...)
  2016-12-18  7:01     ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
@ 2016-12-18  7:01     ` Palmer Dabbelt
  2016-12-19  0:26     ` RISC-V Fixes for 2.28 v2 Alan Modra
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

    jalr rd,offset(rs1)

rather than

    jalr rd,rs1,offset

This matches the format of other instructions.
---
 opcodes/riscv-opc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 256e089..69fca09 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -132,11 +132,14 @@ const struct riscv_opcode riscv_opcodes[] =
 {"ret",       "I",   "",  MATCH_JALR | (X_RA << OP_SH_RS1), MASK_JALR | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
 {"jr",        "C",   "d",  MATCH_C_JR, MASK_C_JR, match_rd_nonzero, INSN_ALIAS },
 {"jr",        "I",   "s",  MATCH_JALR, MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jr",        "I",   "o(s)",  MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jr",        "I",   "s,j",  MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "C",   "d",  MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, INSN_ALIAS },
 {"jalr",      "I",   "s",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jalr",      "I",   "o(s)",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "I",   "s,j",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "I",   "d,s",  MATCH_JALR, MASK_JALR | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jalr",      "I",   "d,o(s)",  MATCH_JALR, MASK_JALR, match_opcode, 0 },
 {"jalr",      "I",   "d,s,j",  MATCH_JALR, MASK_JALR, match_opcode, 0 },
 {"j",         "C",   "Ca",  MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS },
 {"j",         "I",   "a",  MATCH_JAL, MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS },
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 4/9] Fix an integer overflow in relocation handling
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
@ 2016-12-18  7:01     ` Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
                       ` (8 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

---
 bfd/elfnn-riscv.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 5976118..461bce3 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2759,7 +2759,7 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 
 /* Traverse all output sections and return the max alignment.  */
 
-static unsigned int
+static bfd_vma
 _bfd_riscv_get_max_alignment (asection *sec)
 {
   unsigned int max_alignment_power = 0;
@@ -2771,7 +2771,7 @@ _bfd_riscv_get_max_alignment (asection *sec)
 	max_alignment_power = o->alignment_power;
     }
 
-  return 1 << max_alignment_power;
+  return (bfd_vma) 1 << max_alignment_power;
 }
 
 /* Relax non-PIC global variable references.  */
@@ -2783,7 +2783,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      struct bfd_link_info *link_info,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
-		      unsigned int max_alignment,
+		      bfd_vma max_alignment,
 		      bfd_vma reserve_size,
 		      bfd_boolean *again)
 {
@@ -2900,7 +2900,7 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
-			unsigned int max_alignment ATTRIBUTE_UNUSED,
+			bfd_vma max_alignment ATTRIBUTE_UNUSED,
 			bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			bfd_boolean *again ATTRIBUTE_UNUSED)
 {
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* RISC-V Fixes for 2.28 v2
  2016-12-16 19:47 ` Palmer Dabbelt
  2016-12-16 23:11   ` Alan Modra
@ 2016-12-18  7:01   ` Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
                       ` (9 more replies)
  1 sibling, 10 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman

Thanks to everyone who reviewed our patches.  I believe I've taken everyone's
feedback into account.  The issues were fairly small, so unless there's any
more feedback I think this should be ready to go.

Here's something that I hope is actually a set of ChangeLog entries this time,
as opposed to whatever I did last time.



opcodes/ChangeLog

2016-12-17 Andrew Waterman <andrew@sifive.com>

	* riscv-opc.c: Correct assembler mnemonic for aqrl AMOs.

2016-12-17 Andrew Waterman <andrew@sifive.com>

	* riscv-opc.c: Fix disassembly of CSR instructions under -Mno-aliases.

2016-12-17 Andrew Waterman <andrew@sifive.com>

	* riscv-opc.c: Add canonical JALR assembly representation.

2016-12-17 Andrew Waterman <andrew@sifive.com>

	* riscv-dis.c: Re-work RISC-V gas flags: now we just support -mabi and
	-march.



gas/ChangeLog

2016-12-17 Andrew Waterman <andrew@sifive.com>

	* config/tc-riscv.c: Don't define our own .p2align.
	* config/tc-riscv.h: Likewise.

2016-12-17 Andrew Waterman <andrew@sifive.com>

	* config/tc-riscv.c: Re-work RISC-V gas flags: now we just support
	-mabi and -march.

	* config/tc-riscv.h: Likewise.
	* doc/as.texinfo: Document -mabi and -march.
	* doc/c-riscv.texi: Likewise.

2016-12-17 Andrew Waterman <andrew@sifive.com>
	   Kuan-Lin Chen <kuanlinchentw@gmail.com>

	* config/tc-riscv.c: Likewise.
	* config/tc-riscv.h: F registers might be 4-type aligned, so always
	specify DWARF2_CIE_DATA_ALIGNMENT is 4.



bfd/ChangeLog

2016-12-17 Andrew Waterman <andrew@sifive.com>

	* elfnn-riscv.c: 

2016-12-17 Andrew Waterman <andrew@sifive.com>

	* elfnn-riscv.c: Fix an integer overflow in relocation handling.

2016-12-17 Andrew Waterman <andrew@sifive.com>

	* elfnn-riscv.c: Formatting changes for RISC-V.
	* elfxx-riscv.c: Likewise.

2016-12-17 Andrew Waterman <andrew@sifive.com>
	   Kuan-Lin Chen <kuanlinchentw@gmail.com>

	* bfd-in2.h: Define some new relocations, needed to support CFI
	relaxation: TPREL_I, TPREL_S, RELAX, SUB6, SET6, SET8, SET16, SET32.
	* elfnn-riscv.c: Implement these new relocations
	* elfxx-riscv.c: Likewise.
	* libbfd.h: Likewise.
	* reloc.c: Likewise.

2016-12-17 Palmer Dabbelt <palmer@dabbelt.com>

	* elfnn-riscv.c: Improve a LD error message when linking elf32 and
	elf64.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 1/9] Improve a LD error message when linking elf32 and elf64
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
                       ` (3 preceding siblings ...)
  2016-12-18  7:01     ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
@ 2016-12-18  7:01     ` Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases Palmer Dabbelt
                       ` (4 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman, Palmer Dabbelt

I recently ran into this error message and found it's not helpful: it
just tells me some temporary file can't be linked.  This slightly
improved one at least tells me it's because of an elf32/elf64 conflict.
---
 bfd/elfnn-riscv.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 4f11cf6..88d5d66 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2561,8 +2561,9 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
     {
       (*_bfd_error_handler)
-	(_("%B: ABI is incompatible with that of the selected emulation"),
-	 ibfd);
+	(_("%B: ABI is incompatible with that of the selected emulation:\n"
+           "  target emulation `%s' does not match `%s'"),
+	 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
       return FALSE;
     }
 
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
                       ` (2 preceding siblings ...)
  2016-12-18  7:01     ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
@ 2016-12-18  7:01     ` Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
                       ` (5 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

sc is a misnomer, because they aren't inherently sc.
---
 opcodes/riscv-opc.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 9ea3b8a..3c732fd 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -343,17 +343,17 @@ const struct riscv_opcode riscv_opcodes[] =
 {"amomaxu.w.rl", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_RL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
 {"amomin.w.rl",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_RL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
 {"amominu.w.rl", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_RL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
-{"lr.w.sc",      "A",   "d,0(s)",    MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, 0 },
-{"sc.w.sc",      "A",   "d,t,0(s)",  MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, 0 },
-{"amoadd.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 },
-{"amoswap.w.sc", "A",   "d,t,0(s)",  MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 },
-{"amoand.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 },
-{"amoor.w.sc",   "A",   "d,t,0(s)",  MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 },
-{"amoxor.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 },
-{"amomax.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 },
-{"amomaxu.w.sc", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
-{"amomin.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
-{"amominu.w.sc", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
+{"lr.w.aqrl",    "A",   "d,0(s)",    MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, 0 },
+{"sc.w.aqrl",    "A",   "d,t,0(s)",  MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, 0 },
+{"amoadd.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 },
+{"amoswap.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 },
+{"amoand.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 },
+{"amoor.w.aqrl",   "A",   "d,t,0(s)",  MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 },
+{"amoxor.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 },
+{"amomax.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 },
+{"amomaxu.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
+{"amomin.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
+{"amominu.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
 {"lr.d",         "64A", "d,0(s)",    MATCH_LR_D, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
 {"sc.d",         "64A", "d,t,0(s)",  MATCH_SC_D, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
 {"amoadd.d",     "64A", "d,t,0(s)",  MATCH_AMOADD_D, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
@@ -387,17 +387,17 @@ const struct riscv_opcode riscv_opcodes[] =
 {"amomaxu.d.rl", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_RL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
 {"amomin.d.rl",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_RL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
 {"amominu.d.rl", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_RL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
-{"lr.d.sc",      "64A", "d,0(s)",    MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
-{"sc.d.sc",      "64A", "d,t,0(s)",  MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
-{"amoadd.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
-{"amoswap.d.sc", "64A", "d,t,0(s)",  MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 },
-{"amoand.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 },
-{"amoor.d.sc",   "64A", "d,t,0(s)",  MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 },
-{"amoxor.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 },
-{"amomax.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 },
-{"amomaxu.d.sc", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
-{"amomin.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
-{"amominu.d.sc", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
+{"lr.d.aqrl",    "64A", "d,0(s)",    MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
+{"sc.d.aqrl",    "64A", "d,t,0(s)",  MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
+{"amoadd.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
+{"amoswap.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 },
+{"amoand.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 },
+{"amoor.d.aqrl",   "64A", "d,t,0(s)",  MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 },
+{"amoxor.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 },
+{"amomax.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 },
+{"amomaxu.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
+{"amomin.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
+{"amominu.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
 
 /* Multiply/Divide instruction subset */
 {"mul",       "M",   "d,s,t",  MATCH_MUL, MASK_MUL, match_opcode, 0 },
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 6/9] Don't define our own .p2align
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
                       ` (5 preceding siblings ...)
  2016-12-18  7:01     ` [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases Palmer Dabbelt
@ 2016-12-18  7:01     ` Palmer Dabbelt
  2016-12-18  7:01     ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
                       ` (2 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-18  7:01 UTC (permalink / raw)
  To: binutils, amodra, vapier; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

---
 gas/config/tc-riscv.c | 96 ++++++++++++++++++++++++++++++---------------------
 gas/config/tc-riscv.h | 14 ++++++--
 2 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 77c92cf..2d953c5 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2185,63 +2185,82 @@ s_bss (int ignore ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
-/* Align to a given power of two.  */
-
 static void
-s_align (int bytes_p)
+riscv_make_nops (char *buf, bfd_vma bytes)
 {
-  int fill_value = 0, fill_value_specified = 0;
-  int min_text_alignment = riscv_opts.rvc ? 2 : 4;
-  int alignment = get_absolute_expression(), bytes;
+  bfd_vma i = 0;
 
-  if (bytes_p)
+  if (bytes % 4 == 2)
     {
-      bytes = alignment;
-      if (bytes < 1 || (bytes & (bytes-1)) != 0)
-	as_bad (_("alignment not a power of 2: %d"), bytes);
-      for (alignment = 0; bytes > 1; bytes >>= 1)
-	alignment++;
+      md_number_to_chars (buf, RVC_NOP, 2);
+      i += 2;
     }
 
-  bytes = 1 << alignment;
+  gas_assert ((bytes - i) % 4 == 0);
 
-  if (alignment < 0 || alignment > 31)
-    as_bad (_("unsatisfiable alignment: %d"), alignment);
+  for ( ; i < bytes; i += 4)
+    md_number_to_chars (buf + i, RISCV_NOP, 4);
+}
 
-  if (*input_line_pointer == ',')
-    {
-      ++input_line_pointer;
-      fill_value = get_absolute_expression ();
-      fill_value_specified = 1;
-    }
+/* Called from md_do_align.  Used to create an alignment frag in a
+   code section by emitting a worst-case NOP sequence that the linker
+   will later relax to the correct number of NOPs.  We can't compute
+   the correct alignment now because of other linker relaxations.  */
+
+bfd_boolean
+riscv_frag_align_code (int n)
+{
+  bfd_vma bytes = (bfd_vma)1 << n;
+  bfd_vma min_text_alignment = riscv_opts.rvc ? 2 : 4;
+
+  /* When not relaxing, riscv_handle_align handles code alignment.  */
+  if (!riscv_opts.relax)
+    return FALSE;
 
-  if (!fill_value_specified
-      && subseg_text_p (now_seg)
-      && bytes > min_text_alignment)
+  if (bytes > min_text_alignment)
     {
-      /* Emit the worst-case NOP string.  The linker will delete any
-	 unnecessary NOPs.  This allows us to support code alignment
-	 in spite of linker relaxations.  */
-      bfd_vma i, worst_case_bytes = bytes - min_text_alignment;
+      bfd_vma worst_case_bytes = bytes - min_text_alignment;
       char *nops = frag_more (worst_case_bytes);
-      for (i = 0; i < worst_case_bytes - 2; i += 4)
-	md_number_to_chars (nops + i, RISCV_NOP, 4);
-      if (i < worst_case_bytes)
-	md_number_to_chars (nops + i, RVC_NOP, 2);
-
       expressionS ex;
+
       ex.X_op = O_constant;
       ex.X_add_number = worst_case_bytes;
 
+      riscv_make_nops (nops, worst_case_bytes);
+
       fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
 		   &ex, FALSE, BFD_RELOC_RISCV_ALIGN);
     }
-  else if (alignment)
-    frag_align (alignment, fill_value, 0);
 
-  record_alignment (now_seg, alignment);
+  return TRUE;
+}
 
-  demand_empty_rest_of_line ();
+/* Implement HANDLE_ALIGN.  */
+
+void
+riscv_handle_align (fragS *fragP)
+{
+  switch (fragP->fr_type)
+    {
+    case rs_align_code:
+      /* When relaxing, riscv_frag_align_code handles code alignment.  */
+      if (!riscv_opts.relax)
+	{
+	  bfd_signed_vma count = fragP->fr_next->fr_address
+				 - fragP->fr_address - fragP->fr_fix;
+
+	  if (count <= 0)
+	    break;
+
+	  count &= MAX_MEM_FOR_RS_ALIGN_CODE;
+	  riscv_make_nops (fragP->fr_literal + fragP->fr_fix, count);
+	  fragP->fr_var = count;
+	}
+      break;
+
+    default:
+      break;
+    }
 }
 
 int
@@ -2488,9 +2507,6 @@ static const pseudo_typeS riscv_pseudo_table[] =
   {"dtprelword", s_dtprel, 4},
   {"dtpreldword", s_dtprel, 8},
   {"bss", s_bss, 0},
-  {"align", s_align, 0},
-  {"p2align", s_align, 0},
-  {"balign", s_align, 1},
   {"uleb128", s_riscv_leb128, 0},
   {"sleb128", s_riscv_leb128, 1},
 
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 5e07fda..5d6b83f 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -48,8 +48,18 @@ extern int riscv_relax_frag (asection *, struct frag *, long);
 #define md_undefined_symbol(name)	(0)
 #define md_operand(x)
 
-/* FIXME: it is unclear if this is used, or if it is even correct.  */
-#define MAX_MEM_FOR_RS_ALIGN_CODE  (1 + 2)
+extern bfd_boolean riscv_frag_align_code (int);
+#define md_do_align(N, FILL, LEN, MAX, LABEL)				\
+  if ((N) != 0 && !(FILL) && !need_pass_2 && subseg_text_p (now_seg))	\
+    {									\
+      if (riscv_frag_align_code (N))					\
+	goto LABEL;							\
+    }
+
+extern void riscv_handle_align (fragS *);
+#define HANDLE_ALIGN riscv_handle_align
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE 7
 
 /* The ISA of the target may change based on command-line arguments.  */
 #define TARGET_FORMAT riscv_target_format()
-- 
2.7.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: RISC-V Fixes for 2.28 v2
  2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
                       ` (8 preceding siblings ...)
  2016-12-18  7:01     ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
@ 2016-12-19  0:26     ` Alan Modra
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
  2016-12-19  6:24       ` RISC-V Fixes for 2.28 v2 Cary Coutant
  9 siblings, 2 replies; 57+ messages in thread
From: Alan Modra @ 2016-12-19  0:26 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils, vapier, Andrew Waterman

On Sat, Dec 17, 2016 at 11:00:00PM -0800, Palmer Dabbelt wrote:
> Here's something that I hope is actually a set of ChangeLog entries this time,

I think that if you had read the link I gave you, you'd know that you
have not complied with ChangeLog requirements.  So, no, this patchset
is not ready to commit.  And yes, writing ChangeLogs is tedious.

Some tips: Create the ChangeLog at the same time as you edit the
source.  Emacs "C-x 4 a" will usually give you a good entry and
mention the function being edited, which was one of the reasons why
your entries fail to be OK.  Put the body of the ChangeLog entry in
the git log, along with a prototype email that will form the basis of
your eventual mailing list post.  That way there isn't much work left
to do later, and leaving some sort of description in the git log is a
really good idea.  Also, this keeps the ChangeLog entry with the patch
rather than putting it in the email covering letter.  Do mention all
substantive changes in the ChangeLog, eg. you missed a mention of
fixing src_mask in the howtos.  For non-substantive changes it's OK to
just write

	* filename.c: Formatting and comment fixes throughout.

and it's OK when making a change to a function signature to write

	* filename.c (some_func): Add blah parameter, use to decide
	blahness.  Update all callers.

ie. you don't need to call out secondary details in perhaps dozens of
functions that need tweaking to pass an extra param to "some_func".

Use
http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/git-merge-changelog.c
to help merge your local ChangeLog entries.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 1/9] Improve a LD error message when linking elf32 and elf64
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
@ 2016-12-19  4:27         ` Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases Palmer Dabbelt
                           ` (7 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman, Palmer Dabbelt

I recently ran into this error message and found it's not helpful: it
just tells me some temporary file can't be linked.  This slightly
improved one at least tells me it's because of an elf32/elf64 conflict.

bfd/ChangeLog

        * elfnn-riscv.c (_bfd_riscv_elf_merge_private_bfd_data): Improve
        error message when linking elf32 and elf64.
---
 bfd/elfnn-riscv.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 4f11cf6..88d5d66 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2561,8 +2561,9 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
     {
       (*_bfd_error_handler)
-	(_("%B: ABI is incompatible with that of the selected emulation"),
-	 ibfd);
+	(_("%B: ABI is incompatible with that of the selected emulation:\n"
+           "  target emulation `%s' does not match `%s'"),
+	 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
       return FALSE;
     }
 
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 7/9] Add canonical JALR assembly representation
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
                           ` (6 preceding siblings ...)
  2016-12-19  4:27         ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
@ 2016-12-19  4:27         ` Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

    jalr rd,offset(rs1)

rather than

    jalr rd,rs1,offset

This matches the format of other instructions.

opcodes/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * riscv-opc.c (riscv_opcodes): Change jr and jalr to "o(s)"
        format.
---
 opcodes/riscv-opc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 256e089..69fca09 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -132,11 +132,14 @@ const struct riscv_opcode riscv_opcodes[] =
 {"ret",       "I",   "",  MATCH_JALR | (X_RA << OP_SH_RS1), MASK_JALR | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
 {"jr",        "C",   "d",  MATCH_C_JR, MASK_C_JR, match_rd_nonzero, INSN_ALIAS },
 {"jr",        "I",   "s",  MATCH_JALR, MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jr",        "I",   "o(s)",  MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jr",        "I",   "s,j",  MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "C",   "d",  MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, INSN_ALIAS },
 {"jalr",      "I",   "s",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jalr",      "I",   "o(s)",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "I",   "s,j",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "I",   "d,s",  MATCH_JALR, MASK_JALR | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jalr",      "I",   "d,o(s)",  MATCH_JALR, MASK_JALR, match_opcode, 0 },
 {"jalr",      "I",   "d,s,j",  MATCH_JALR, MASK_JALR, match_opcode, 0 },
 {"j",         "C",   "Ca",  MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS },
 {"j",         "I",   "a",  MATCH_JAL, MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS },
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 3/9] Rework RISC-V relocations
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
                           ` (3 preceding siblings ...)
  2016-12-19  4:27         ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
@ 2016-12-19  4:27         ` Palmer Dabbelt
  2016-12-19  6:10           ` Alan Modra
  2016-12-19  4:27         ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
                           ` (4 subsequent siblings)
  9 siblings, 1 reply; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

Before this commit we didn't cleanly support CFI directives because the
internal offsets used to get relaxed which broke them.  This patch
significantly reworks how we handle linker relaxations:

 * DWARF is now properly supported

 * There is a ".option norelax" to disable relaxations, for when users
   write assembly that can't be relaxed (if it's to be later patched up,
   for example).

 * There is an additional _RELAX relocation that specifies when previous
   relocations can be relaxed.

We're in the process of documenting the RISC-V ELF ABI, which will
include documentation of our relocations

  https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md

but we expect that this relocation set will remain ABI compatible in the
future (ie, it's safe to release).

Thanks to Kuan-Lin Chen for figuring out how to correctly relax the
debug info!

bfd/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>
           Kuan-Lin Chen <kuanlinchentw@gmail.com>

        * reloc.c (BFD_RELOC_RISCV_TPREL_I): New relocation.
        * reloc.c (BFD_RELOC_RISCV_TPREL_S): Likewise.
        * reloc.c (BFD_RELOC_RISCV_RELAX): Likewise.
        * reloc.c (BFD_RELOC_RISCV_CFA): Likewise.
        * reloc.c (BFD_RELOC_RISCV_SUB6): Likewise.
        * reloc.c (BFD_RELOC_RISCV_SET8): Likewise.
        * reloc.c (BFD_RELOC_RISCV_SET8): Likewise.
        * reloc.c (BFD_RELOC_RISCV_SET16): Likewise.
        * reloc.c (BFD_RELOC_RISCV_SET32): Likewise.
        * bfd-in2.h: Regenerate.
        * libbfd.h: Likewise.
        * elfnn-riscv.c (perform_relocation): Handle the new
        relocations.
        * elfnn-riscv.c (_bfd_riscv_relax_tls_le): Likewise.
        * elfnn-riscv.c (_bfd_riscv_relax_align): Likewise.
        * elfnn-riscv.c (_bfd_riscv_relax_section): Likewise.
        * elfnn-riscv.c (howto_table): Likewise.
        * elfnn-riscv.c (riscv_reloc_map): Likewise.

2016-12-14 Andrew Waterman <andrew@sifive.com>
           Kuan-Lin Chen <kuanlinchentw@gmail.com>

        * elfnn-riscv.c (relax_func_t): New type.
        * elfnn-riscv.c (_bfd_riscv_relax_call): Add reserve_size
        argument, which controls the maximal offset pessimism.
        * elfnn-riscv.c (_bfd_riscv_relax_lui): Likewise.
        * elfnn-riscv.c (_bfd_riscv_relax_tls_le): Likewise.
        * elfnn-riscv.c (_bfd_riscv_relax_align): Likewise.
        * elfnn-riscv.c (_bfd_riscv_relax_section): Compute the required
        reserve size when relocating and use it to when calling
        relax_func.

gas/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>
           Kuan-Lin Chen <kuanlinchentw@gmail.com>

        * config/tc-riscv.c (riscv_set_options): Add relax.
        * config/tc-riscv.c (riscv_opts): Likewise.
        * config/tc-riscv.c (s_riscv_option): Add relax and norelax.
        * config/tc-riscv.c (riscv_apply_const_reloc): New function.
        * config/tc-riscv.c (append_insn): Move constant relocation
        handling to riscv_apply_const_reloc.
        * config/tc-riscv.c (md_pcrel_from): Likewise.
        * config/tc-riscv.c (parse_relocation): Skip BFD_RELOC_UNUSED.
        * config/tc-riscv.c (md_pcrel_from): Handle
        BFD_RELOC_RISCV_SUB6, BFD_RELOC_RISCV_RELAX,
        BFD_RELOC_RISCV_CFA.
        * config/tc-riscv.c (md_apply_fix): Likewise.
        * config/tc-riscv.c (riscv_pre_output_hook): New function.
        * config/tc-riscv.h (md_pre_output_hook): Use
        riscv_pre_output_hook.
        * config/tc-riscv.h (DWARF_CIE_DATA_ALIGNMENT): Always -4.
---
 bfd/bfd-in2.h         |   9 +++
 bfd/elfnn-riscv.c     |  93 ++++++++++++++++++----
 bfd/elfxx-riscv.c     | 128 ++++++++++++++++++++++++++++++
 bfd/libbfd.h          |   9 +++
 bfd/reloc.c           |  18 +++++
 gas/config/tc-riscv.c | 213 +++++++++++++++++++++++++++++++++++++-------------
 gas/config/tc-riscv.h |   7 +-
 include/elf/riscv.h   |   8 ++
 8 files changed, 416 insertions(+), 69 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 1c6b70f..b5ac178 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -4737,6 +4737,15 @@ number for the SBIC, SBIS, SBI and CBI instructions  */
   BFD_RELOC_RISCV_RVC_LUI,
   BFD_RELOC_RISCV_GPREL_I,
   BFD_RELOC_RISCV_GPREL_S,
+  BFD_RELOC_RISCV_TPREL_I,
+  BFD_RELOC_RISCV_TPREL_S,
+  BFD_RELOC_RISCV_RELAX,
+  BFD_RELOC_RISCV_CFA,
+  BFD_RELOC_RISCV_SUB6,
+  BFD_RELOC_RISCV_SET6,
+  BFD_RELOC_RISCV_SET8,
+  BFD_RELOC_RISCV_SET16,
+  BFD_RELOC_RISCV_SET32,
 
 /* Renesas RL78 Relocations.  */
   BFD_RELOC_RL78_NEG8,
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index e18bd71..5976118 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1493,6 +1493,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_LO12_I:
     case R_RISCV_GPREL_I:
     case R_RISCV_TPREL_LO12_I:
+    case R_RISCV_TPREL_I:
     case R_RISCV_PCREL_LO12_I:
       value = ENCODE_ITYPE_IMM (value);
       break;
@@ -1500,6 +1501,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_LO12_S:
     case R_RISCV_GPREL_S:
     case R_RISCV_TPREL_LO12_S:
+    case R_RISCV_TPREL_S:
     case R_RISCV_PCREL_LO12_S:
       value = ENCODE_STYPE_IMM (value);
       break;
@@ -1548,10 +1550,15 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_ADD16:
     case R_RISCV_ADD32:
     case R_RISCV_ADD64:
+    case R_RISCV_SUB6:
     case R_RISCV_SUB8:
     case R_RISCV_SUB16:
     case R_RISCV_SUB32:
     case R_RISCV_SUB64:
+    case R_RISCV_SET6:
+    case R_RISCV_SET8:
+    case R_RISCV_SET16:
+    case R_RISCV_SET32:
     case R_RISCV_TLS_DTPREL32:
     case R_RISCV_TLS_DTPREL64:
       break;
@@ -1817,6 +1824,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
       switch (r_type)
 	{
 	case R_RISCV_NONE:
+	case R_RISCV_RELAX:
 	case R_RISCV_TPREL_ADD:
 	case R_RISCV_COPY:
 	case R_RISCV_JUMP_SLOT:
@@ -1830,6 +1838,10 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_RVC_LUI:
 	case R_RISCV_LO12_I:
 	case R_RISCV_LO12_S:
+	case R_RISCV_SET6:
+	case R_RISCV_SET8:
+	case R_RISCV_SET16:
+	case R_RISCV_SET32:
 	  /* These require no special handling beyond perform_relocation.  */
 	  break;
 
@@ -1923,6 +1935,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  }
 	  break;
 
+	case R_RISCV_SUB6:
 	case R_RISCV_SUB8:
 	case R_RISCV_SUB16:
 	case R_RISCV_SUB32:
@@ -1953,6 +1966,11 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_TPREL_LO12_I:
 	case R_RISCV_TPREL_LO12_S:
 	  relocation = tpoff (info, relocation);
+	  break;
+
+	case R_RISCV_TPREL_I:
+	case R_RISCV_TPREL_S:
+	  relocation = tpoff (info, relocation);
 	  if (VALID_ITYPE_IMM (relocation + rel->r_addend))
 	    {
 	      /* We can use tp as the base register.  */
@@ -1961,6 +1979,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	      insn |= X_TP << OP_SH_RS1;
 	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
 	    }
+	  else
+	    r = bfd_reloc_overflow;
 	  break;
 
 	case R_RISCV_GPREL_I:
@@ -2668,6 +2688,11 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count)
   return TRUE;
 }
 
+typedef bfd_boolean (*relax_func_t) (bfd *, asection *, asection *,
+				     struct bfd_link_info *,
+				     Elf_Internal_Rela *,
+				     bfd_vma, bfd_vma, bfd_vma, bfd_boolean *);
+
 /* Relax AUIPC + JALR into JAL.  */
 
 static bfd_boolean
@@ -2675,7 +2700,8 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 		       struct bfd_link_info *link_info,
 		       Elf_Internal_Rela *rel,
 		       bfd_vma symval,
-		       unsigned int max_alignment,
+		       bfd_vma max_alignment,
+		       bfd_vma reserve_size ATTRIBUTE_UNUSED,
 		       bfd_boolean *again)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2758,6 +2784,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
 		      unsigned int max_alignment,
+		      bfd_vma reserve_size,
 		      bfd_boolean *again)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2773,8 +2800,10 @@ _bfd_riscv_relax_lui (bfd *abfd,
   /* Is the reference in range of x0 or gp?
      Valid gp range conservatively because of alignment issue.  */
   if (VALID_ITYPE_IMM (symval)
-      || (symval >= gp && VALID_ITYPE_IMM (symval - gp + max_alignment))
-      || (symval < gp && VALID_ITYPE_IMM (symval - gp - max_alignment)))
+      || (symval >= gp
+	  && VALID_ITYPE_IMM (symval - gp + max_alignment + reserve_size))
+      || (symval < gp
+	  && VALID_ITYPE_IMM (symval - gp - max_alignment - reserve_size)))
     {
       unsigned sym = ELFNN_R_SYM (rel->r_info);
       switch (ELFNN_R_TYPE (rel->r_info))
@@ -2832,20 +2861,35 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
 			 struct bfd_link_info *link_info,
 			 Elf_Internal_Rela *rel,
 			 bfd_vma symval,
-			 unsigned int max_alignment ATTRIBUTE_UNUSED,
+			 bfd_vma max_alignment ATTRIBUTE_UNUSED,
+			 bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			 bfd_boolean *again)
 {
   /* See if this symbol is in range of tp.  */
   if (RISCV_CONST_HIGH_PART (tpoff (link_info, symval)) != 0)
     return TRUE;
 
-  /* We can delete the unnecessary LUI and tp add.  The LO12 reloc will be
-     made directly tp-relative.  */
   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
-  rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
+  switch (ELFNN_R_TYPE (rel->r_info))
+    {
+    case R_RISCV_TPREL_LO12_I:
+      rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_I);
+      return TRUE;
 
-  *again = TRUE;
-  return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
+    case R_RISCV_TPREL_LO12_S:
+      rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_S);
+      return TRUE;
+
+    case R_RISCV_TPREL_HI20:
+    case R_RISCV_TPREL_ADD:
+      /* We can delete the unnecessary instruction and reloc.  */
+      rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
+      *again = TRUE;
+      return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
+
+    default:
+      abort ();
+    }
 }
 
 /* Implement R_RISCV_ALIGN by deleting excess alignment NOPs.  */
@@ -2857,6 +2901,7 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
 			unsigned int max_alignment ATTRIBUTE_UNUSED,
+			bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			bfd_boolean *again ATTRIBUTE_UNUSED)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2909,7 +2954,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
   Elf_Internal_Rela *relocs;
   bfd_boolean ret = FALSE;
   unsigned int i;
-  unsigned int max_alignment;
+  bfd_vma max_alignment, reserve_size = 0;
 
   *again = FALSE;
 
@@ -2935,7 +2980,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
     {
       asection *sym_sec;
       Elf_Internal_Rela *rel = relocs + i;
-      typeof (&_bfd_riscv_relax_call) relax_func = NULL;
+      relax_func_t relax_func;
       int type = ELFNN_R_TYPE (rel->r_info);
       bfd_vma symval;
 
@@ -2947,13 +2992,26 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 		   || type == R_RISCV_LO12_I
 		   || type == R_RISCV_LO12_S)
 	    relax_func = _bfd_riscv_relax_lui;
-	  else if (type == R_RISCV_TPREL_HI20 || type == R_RISCV_TPREL_ADD)
+	  else if (type == R_RISCV_TPREL_HI20
+		   || type == R_RISCV_TPREL_ADD
+		   || type == R_RISCV_TPREL_LO12_I
+		   || type == R_RISCV_TPREL_LO12_S)
 	    relax_func = _bfd_riscv_relax_tls_le;
+	  else
+	    continue;
+
+	  /* Only relax this reloc if it is paired with R_RISCV_RELAX.  */
+	  if (i == sec->reloc_count - 1
+	      || ELFNN_R_TYPE ((rel + 1)->r_info) != R_RISCV_RELAX
+	      || rel->r_offset != (rel + 1)->r_offset)
+	    continue;
+
+	  /* Skip over the R_RISCV_RELAX.  */
+	  i++;
 	}
       else if (type == R_RISCV_ALIGN)
 	relax_func = _bfd_riscv_relax_align;
-
-      if (!relax_func)
+      else
 	continue;
 
       data->relocs = relocs;
@@ -2978,6 +3036,8 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	  /* A local symbol.  */
 	  Elf_Internal_Sym *isym = ((Elf_Internal_Sym *) symtab_hdr->contents
 				    + ELFNN_R_SYM (rel->r_info));
+	  reserve_size = (isym->st_size - rel->r_addend) > isym->st_size
+	    ? 0 : isym->st_size - rel->r_addend;
 
 	  if (isym->st_shndx == SHN_UNDEF)
 	    sym_sec = sec, symval = sec_addr (sec) + rel->r_offset;
@@ -3011,13 +3071,16 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	  else
 	    symval = sec_addr (h->root.u.def.section) + h->root.u.def.value;
 
+	  if (h->type != STT_FUNC)
+	    reserve_size =
+	      (h->size - rel->r_addend) > h->size ? 0 : h->size - rel->r_addend;
 	  sym_sec = h->root.u.def.section;
 	}
 
       symval += rel->r_addend;
 
       if (!relax_func (abfd, sec, sym_sec, info, rel, symval,
-		       max_alignment, again))
+		       max_alignment, reserve_size, again))
 	goto fail;
     }
 
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 0fb250d..3d935cf 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -713,6 +713,126 @@ static reloc_howto_type howto_table[] =
 	 0,				/* src_mask */
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
+
+  /* TP-relative TLS LE load.  */
+  HOWTO (R_RISCV_TPREL_I,		/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TPREL_I",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* TP-relative TLS LE store.  */
+  HOWTO (R_RISCV_TPREL_S,		/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TPREL_S",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* The paired relocation may be relaxed.  */
+  HOWTO (R_RISCV_RELAX,			/* type */
+	 0,				/* rightshift */
+	 3,				/* size */
+	 0,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_RELAX",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 6-bit in-place addition, for local label subtraction.  */
+  HOWTO (R_RISCV_SUB6,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SUB6",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0x3f,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 6-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET6,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET6",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0x3f,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 8-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET8,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET8",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 16-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET16,			/* type */
+	 0,				/* rightshift */
+	 1,				/* size */
+	 16,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET16",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 32-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET32,			/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET32",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
 };
 
 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
@@ -766,6 +886,14 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
   { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
   { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
+  { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
+  { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
+  { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
+  { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
+  { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
+  { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
+  { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
+  { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
 };
 
 /* Given a BFD reloc type, return a howto structure.  */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 5ec3993..76bbd09 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2204,6 +2204,15 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RISCV_RVC_LUI",
   "BFD_RELOC_RISCV_GPREL_I",
   "BFD_RELOC_RISCV_GPREL_S",
+  "BFD_RELOC_RISCV_TPREL_I",
+  "BFD_RELOC_RISCV_TPREL_S",
+  "BFD_RELOC_RISCV_RELAX",
+  "BFD_RELOC_RISCV_CFA",
+  "BFD_RELOC_RISCV_SUB6",
+  "BFD_RELOC_RISCV_SET6",
+  "BFD_RELOC_RISCV_SET8",
+  "BFD_RELOC_RISCV_SET16",
+  "BFD_RELOC_RISCV_SET32",
   "BFD_RELOC_RL78_NEG8",
   "BFD_RELOC_RL78_NEG16",
   "BFD_RELOC_RL78_NEG24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 56cd79b..3c7b606 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5124,6 +5124,24 @@ ENUMX
   BFD_RELOC_RISCV_GPREL_I
 ENUMX
   BFD_RELOC_RISCV_GPREL_S
+ENUMX
+  BFD_RELOC_RISCV_TPREL_I
+ENUMX
+  BFD_RELOC_RISCV_TPREL_S
+ENUMX
+  BFD_RELOC_RISCV_RELAX
+ENUMX
+  BFD_RELOC_RISCV_CFA
+ENUMX
+  BFD_RELOC_RISCV_SUB6
+ENUMX
+  BFD_RELOC_RISCV_SET6
+ENUMX
+  BFD_RELOC_RISCV_SET8
+ENUMX
+  BFD_RELOC_RISCV_SET16
+ENUMX
+  BFD_RELOC_RISCV_SET32
 ENUMDOC
   RISC-V relocations.
 
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index d8a627d..d011864 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -74,12 +74,14 @@ struct riscv_set_options
 {
   int pic; /* Generate position-independent code.  */
   int rvc; /* Generate RVC code.  */
+  int relax; /* Emit relocs the linker is allowed to relax.  */
 };
 
 static struct riscv_set_options riscv_opts =
 {
   0,	/* pic */
   0,	/* rvc */
+  1,	/* relax */
 };
 
 static void
@@ -648,6 +650,28 @@ md_begin (void)
   record_alignment (text_section, riscv_opts.rvc ? 1 : 2);
 }
 
+static insn_t
+riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type, bfd_vma value)
+{
+  switch (reloc_type)
+    {
+    case BFD_RELOC_32:
+      return value;
+
+    case BFD_RELOC_RISCV_HI20:
+      return ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
+
+    case BFD_RELOC_RISCV_LO12_S:
+      return ENCODE_STYPE_IMM (value);
+
+    case BFD_RELOC_RISCV_LO12_I:
+      return ENCODE_ITYPE_IMM (value);
+
+    default:
+      abort ();
+    }
+}
+
 /* Output an instruction.  IP is the instruction information.
    ADDRESS_EXPR is an operand of the instruction to be used with
    RELOC_TYPE.  */
@@ -676,43 +700,22 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
 	  return;
 	}
       else if (address_expr->X_op == O_constant)
+	ip->insn_opcode |= riscv_apply_const_reloc (reloc_type,
+						    address_expr->X_add_number);
+      else
 	{
-	  switch (reloc_type)
-	    {
-	    case BFD_RELOC_32:
-	      ip->insn_opcode |= address_expr->X_add_number;
-	      goto append;
+	  howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
+	  if (howto == NULL)
+	    as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
 
-	    case BFD_RELOC_RISCV_HI20:
-	      {
-		insn_t imm = RISCV_CONST_HIGH_PART (address_expr->X_add_number);
-		ip->insn_opcode |= ENCODE_UTYPE_IMM (imm);
-		goto append;
-	      }
-
-	    case BFD_RELOC_RISCV_LO12_S:
-	      ip->insn_opcode |= ENCODE_STYPE_IMM (address_expr->X_add_number);
-	      goto append;
+	  ip->fixp = fix_new_exp (ip->frag, ip->where,
+				  bfd_get_reloc_size (howto),
+				  address_expr, FALSE, reloc_type);
 
-	    case BFD_RELOC_RISCV_LO12_I:
-	      ip->insn_opcode |= ENCODE_ITYPE_IMM (address_expr->X_add_number);
-	      goto append;
-
-	    default:
-	      break;
-	    }
+	  ip->fixp->fx_tcbit = riscv_opts.relax;
 	}
-
-	howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
-	if (howto == NULL)
-	  as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
-
-	ip->fixp = fix_new_exp (ip->frag, ip->where,
-				bfd_get_reloc_size (howto),
-				address_expr, FALSE, reloc_type);
     }
 
-append:
   add_fixed_insn (ip);
   install_insn (ip);
 }
@@ -1085,7 +1088,8 @@ parse_relocation (char **str, bfd_reloc_code_real_type *reloc,
 
 	/* Check whether the output BFD supports this relocation.
 	   If not, issue an error and fall back on something safe.  */
-	if (!bfd_reloc_type_lookup (stdoutput, percent_op->reloc))
+	if (*reloc != BFD_RELOC_UNUSED
+	    && !bfd_reloc_type_lookup (stdoutput, *reloc))
 	  {
 	    as_bad ("relocation %s isn't supported by the current ABI",
 		    percent_op->str);
@@ -1826,45 +1830,56 @@ md_pcrel_from (fixS *fixP)
 void
 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
+  unsigned int subtype;
   bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
+  bfd_boolean relaxable = FALSE;
 
   /* Remember value for tc_gen_reloc.  */
   fixP->fx_addnumber = *valP;
 
   switch (fixP->fx_r_type)
     {
-    case BFD_RELOC_RISCV_TLS_GOT_HI20:
-    case BFD_RELOC_RISCV_TLS_GD_HI20:
-    case BFD_RELOC_RISCV_TLS_DTPREL32:
-    case BFD_RELOC_RISCV_TLS_DTPREL64:
-    case BFD_RELOC_RISCV_TPREL_HI20:
-    case BFD_RELOC_RISCV_TPREL_LO12_I:
-    case BFD_RELOC_RISCV_TPREL_LO12_S:
-    case BFD_RELOC_RISCV_TPREL_ADD:
-      S_SET_THREAD_LOCAL (fixP->fx_addsy);
-      /* Fall through.  */
-
-    case BFD_RELOC_RISCV_GOT_HI20:
-    case BFD_RELOC_RISCV_PCREL_HI20:
     case BFD_RELOC_RISCV_HI20:
     case BFD_RELOC_RISCV_LO12_I:
     case BFD_RELOC_RISCV_LO12_S:
+      bfd_putl32 (riscv_apply_const_reloc (fixP->fx_r_type, *valP)
+		  | bfd_getl32 (buf), buf);
+      relaxable = TRUE;
+      break;
+
+    case BFD_RELOC_RISCV_GOT_HI20:
+    case BFD_RELOC_RISCV_PCREL_HI20:
     case BFD_RELOC_RISCV_ADD8:
     case BFD_RELOC_RISCV_ADD16:
     case BFD_RELOC_RISCV_ADD32:
     case BFD_RELOC_RISCV_ADD64:
+    case BFD_RELOC_RISCV_SUB6:
     case BFD_RELOC_RISCV_SUB8:
     case BFD_RELOC_RISCV_SUB16:
     case BFD_RELOC_RISCV_SUB32:
     case BFD_RELOC_RISCV_SUB64:
-      gas_assert (fixP->fx_addsy != NULL);
-      /* Nothing needed to do.  The value comes from the reloc entry.  */
+    case BFD_RELOC_RISCV_RELAX:
+      break;
+
+    case BFD_RELOC_RISCV_TPREL_HI20:
+    case BFD_RELOC_RISCV_TPREL_LO12_I:
+    case BFD_RELOC_RISCV_TPREL_LO12_S:
+    case BFD_RELOC_RISCV_TPREL_ADD:
+      relaxable = TRUE;
+      /* Fall through.  */
+
+    case BFD_RELOC_RISCV_TLS_GOT_HI20:
+    case BFD_RELOC_RISCV_TLS_GD_HI20:
+    case BFD_RELOC_RISCV_TLS_DTPREL32:
+    case BFD_RELOC_RISCV_TLS_DTPREL64:
+      S_SET_THREAD_LOCAL (fixP->fx_addsy);
       break;
 
     case BFD_RELOC_64:
     case BFD_RELOC_32:
     case BFD_RELOC_16:
     case BFD_RELOC_8:
+    case BFD_RELOC_RISCV_CFA:
       if (fixP->fx_addsy && fixP->fx_subsy)
 	{
 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
@@ -1895,6 +1910,49 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
 	      break;
 
+	    case BFD_RELOC_RISCV_CFA:
+	      /* Load the byte to get the subtype.  */
+	      subtype = bfd_get_8 (NULL, &fixP->fx_frag->fr_literal[fixP->fx_where]);
+	      switch (subtype)
+		{
+		case DW_CFA_advance_loc1:
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET8;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
+		  break;
+
+		case DW_CFA_advance_loc2:
+		  fixP->fx_size = 2;
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_size = 2;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET16;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
+		  break;
+
+		case DW_CFA_advance_loc4:
+		  fixP->fx_size = 4;
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_size = 4;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET32;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
+		  break;
+
+		default:
+		  if (subtype < 0x80 && (subtype & 0x40))
+		    {
+		      /* DW_CFA_advance_loc */
+		      fixP->fx_r_type = BFD_RELOC_RISCV_SET6;
+		      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB6;
+		    }
+		  else
+		    as_fatal (_("internal error: bad CFA value #%d"), subtype);
+		  break;
+		}
+	      break;
+
 	    default:
 	      /* This case is unreachable.  */
 	      abort ();
@@ -1954,10 +2012,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	}
       break;
 
-    case BFD_RELOC_RISCV_PCREL_LO12_S:
-    case BFD_RELOC_RISCV_PCREL_LO12_I:
     case BFD_RELOC_RISCV_CALL:
     case BFD_RELOC_RISCV_CALL_PLT:
+      relaxable = TRUE;
+      break;
+
+    case BFD_RELOC_RISCV_PCREL_LO12_S:
+    case BFD_RELOC_RISCV_PCREL_LO12_I:
     case BFD_RELOC_RISCV_ALIGN:
       break;
 
@@ -1966,8 +2027,54 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL)
 	as_fatal (_("internal error: bad relocation #%d"), fixP->fx_r_type);
     }
+
+  /* Add an R_RISCV_RELAX reloc if the reloc is relaxable.  */
+  if (relaxable && fixP->fx_tcbit && fixP->fx_addsy != NULL)
+    {
+      fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
+      fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL;
+      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELAX;
+    }
 }
 
+/* Because the value of .cfi_remember_state may changed after relaxation,
+   we insert a fix to relocate it again in link-time.  */
+
+void
+riscv_pre_output_hook (void)
+{
+  const frchainS *frch;
+  const asection *s;
+
+  for (s = stdoutput->sections; s; s = s->next)
+    for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next)
+      {
+	const fragS *frag;
+
+	for (frag = frch->frch_root; frag; frag = frag->fr_next)
+	  {
+	    if (frag->fr_type == rs_cfa)
+	      {
+		const fragS *loc4_frag;
+		expressionS exp;
+
+		symbolS *add_symbol = frag->fr_symbol->sy_value.X_add_symbol;
+		symbolS *op_symbol = frag->fr_symbol->sy_value.X_op_symbol;
+
+		exp.X_op = O_subtract;
+		exp.X_add_symbol = add_symbol;
+		exp.X_add_number = 0;
+		exp.X_op_symbol = op_symbol;
+
+		loc4_frag = (fragS *) frag->fr_opcode;
+		fix_new_exp (loc4_frag, (int) frag->fr_offset, 1, &exp, 0,
+			     BFD_RELOC_RISCV_CFA);
+	      }
+	  }
+      }
+}
+
+
 /* This structure is used to hold a stack of .option values.  */
 
 struct riscv_option_stack
@@ -1998,10 +2105,10 @@ 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, "relax") == 0)
+    riscv_opts.relax = TRUE;
+  else if (strcmp (name, "norelax") == 0)
+    riscv_opts.relax = FALSE;
   else if (strcmp (name, "push") == 0)
     {
       struct riscv_option_stack *s;
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index c2a11ce..32cf3ee 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -61,6 +61,9 @@ extern void riscv_after_parse_args (void);
 #define md_parse_long_option(arg) riscv_parse_long_option (arg)
 extern int riscv_parse_long_option (const char *);
 
+#define md_pre_output_hook riscv_pre_output_hook()
+extern void riscv_pre_output_hook (void);
+
 /* Let the linker resolve all the relocs due to relaxation.  */
 #define tc_fix_adjustable(fixp) 0
 #define md_allow_local_subtract(l,r,s) 0
@@ -93,7 +96,9 @@ extern int tc_riscv_regname_to_dw2regnum (char *);
 
 extern unsigned xlen;
 #define DWARF2_DEFAULT_RETURN_COLUMN X_RA
-#define DWARF2_CIE_DATA_ALIGNMENT (-(int) (xlen / 8))
+
+/* Even on RV64, use 4-byte alignment, as F registers may be only 32 bits.  */
+#define DWARF2_CIE_DATA_ALIGNMENT -4
 
 #define elf_tc_final_processing riscv_elf_final_processing
 extern void riscv_elf_final_processing (void);
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 8415659..4407611 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -79,6 +79,14 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   RELOC_NUMBER (R_RISCV_RVC_LUI, 46)
   RELOC_NUMBER (R_RISCV_GPREL_I, 47)
   RELOC_NUMBER (R_RISCV_GPREL_S, 48)
+  RELOC_NUMBER (R_RISCV_TPREL_I, 49)
+  RELOC_NUMBER (R_RISCV_TPREL_S, 50)
+  RELOC_NUMBER (R_RISCV_RELAX, 51)
+  RELOC_NUMBER (R_RISCV_SUB6, 52)
+  RELOC_NUMBER (R_RISCV_SET6, 53)
+  RELOC_NUMBER (R_RISCV_SET8, 54)
+  RELOC_NUMBER (R_RISCV_SET16, 55)
+  RELOC_NUMBER (R_RISCV_SET32, 56)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Processor specific flags for the ELF header e_flags field.  */
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
@ 2016-12-19  4:27         ` Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
                           ` (6 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

This fixes https://github.com/riscv/riscv-binutils-gdb/issues/36.

opcodes/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * riscv-opc.c (riscv_opcodes): Mark the rd* and csr* aliases as
        INSN_ALIAS.
---
 opcodes/riscv-opc.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 69fca09..9ea3b8a 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -264,12 +264,12 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fence",     "I",   "",  MATCH_FENCE | MASK_PRED | MASK_SUCC, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
 {"fence",     "I",   "P,Q",  MATCH_FENCE, MASK_FENCE | MASK_RD | MASK_RS1 | (MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 },
 {"fence.i",   "I",   "",  MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 },
-{"rdcycle",   "I",   "d",  MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, 0 },
-{"rdinstret", "I",   "d",  MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, 0 },
-{"rdtime",    "I",   "d",  MATCH_RDTIME, MASK_RDTIME, match_opcode, 0 },
-{"rdcycleh",  "32I", "d",  MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, 0 },
-{"rdinstreth","32I", "d",  MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, 0 },
-{"rdtimeh",   "32I", "d",  MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, 0 },
+{"rdcycle",   "I",   "d",  MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, INSN_ALIAS },
+{"rdinstret", "I",   "d",  MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, INSN_ALIAS },
+{"rdtime",    "I",   "d",  MATCH_RDTIME, MASK_RDTIME, match_opcode, INSN_ALIAS },
+{"rdcycleh",  "32I", "d",  MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, INSN_ALIAS },
+{"rdinstreth","32I", "d",  MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, INSN_ALIAS },
+{"rdtimeh",   "32I", "d",  MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, INSN_ALIAS },
 {"ecall",     "I",   "",    MATCH_SCALL, MASK_SCALL, match_opcode, 0 },
 {"scall",     "I",   "",    MATCH_SCALL, MASK_SCALL, match_opcode, 0 },
 {"xori",      "I",   "d,s,j",  MATCH_XORI, MASK_XORI, match_opcode, 0 },
@@ -592,25 +592,25 @@ const struct riscv_opcode riscv_opcodes[] =
 {"c.fsw",     "32C", "CD,Ck(Cs)",  MATCH_C_FSW, MASK_C_FSW, match_opcode, 0 },
 
 /* Supervisor instructions */
-{"csrr",      "I",   "d,E",  MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, 0 },
-{"csrwi",     "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, 0 },
-{"csrw",      "I",   "E,s",  MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, 0 },
-{"csrw",      "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, 0 },
-{"csrsi",     "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, 0 },
-{"csrs",      "I",   "E,s",  MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, 0 },
-{"csrs",      "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, 0 },
-{"csrci",     "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, 0 },
-{"csrc",      "I",   "E,s",  MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, 0 },
-{"csrc",      "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, 0 },
-{"csrrw",     "I",   "d,E,s",  MATCH_CSRRW, MASK_CSRRW, match_opcode, 0 },
-{"csrrw",     "I",   "d,E,Z",  MATCH_CSRRWI, MASK_CSRRWI, match_opcode, 0 },
-{"csrrs",     "I",   "d,E,s",  MATCH_CSRRS, MASK_CSRRS, match_opcode, 0 },
-{"csrrs",     "I",   "d,E,Z",  MATCH_CSRRSI, MASK_CSRRSI, match_opcode, 0 },
-{"csrrc",     "I",   "d,E,s",  MATCH_CSRRC, MASK_CSRRC, match_opcode, 0 },
-{"csrrc",     "I",   "d,E,Z",  MATCH_CSRRCI, MASK_CSRRCI, match_opcode, 0 },
+{"csrr",      "I",   "d,E",  MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, INSN_ALIAS },
+{"csrwi",     "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrsi",     "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrci",     "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrw",      "I",   "E,s",  MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrw",      "I",   "E,Z",  MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrs",      "I",   "E,s",  MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrs",      "I",   "E,Z",  MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrc",      "I",   "E,s",  MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, INSN_ALIAS },
+{"csrc",      "I",   "E,Z",  MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, INSN_ALIAS },
 {"csrrwi",    "I",   "d,E,Z",  MATCH_CSRRWI, MASK_CSRRWI, match_opcode, 0 },
 {"csrrsi",    "I",   "d,E,Z",  MATCH_CSRRSI, MASK_CSRRSI, match_opcode, 0 },
 {"csrrci",    "I",   "d,E,Z",  MATCH_CSRRCI, MASK_CSRRCI, match_opcode, 0 },
+{"csrrw",     "I",   "d,E,s",  MATCH_CSRRW, MASK_CSRRW, match_opcode, 0 },
+{"csrrw",     "I",   "d,E,Z",  MATCH_CSRRWI, MASK_CSRRWI, match_opcode, INSN_ALIAS },
+{"csrrs",     "I",   "d,E,s",  MATCH_CSRRS, MASK_CSRRS, match_opcode, 0 },
+{"csrrs",     "I",   "d,E,Z",  MATCH_CSRRSI, MASK_CSRRSI, match_opcode, INSN_ALIAS },
+{"csrrc",     "I",   "d,E,s",  MATCH_CSRRC, MASK_CSRRC, match_opcode, 0 },
+{"csrrc",     "I",   "d,E,Z",  MATCH_CSRRCI, MASK_CSRRCI, match_opcode, INSN_ALIAS },
 {"uret",      "I",   "",     MATCH_URET, MASK_URET, match_opcode, 0 },
 {"sret",      "I",   "",     MATCH_SRET, MASK_SRET, match_opcode, 0 },
 {"hret",      "I",   "",     MATCH_HRET, MASK_HRET, match_opcode, 0 },
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* RISC-V Fixes for 2.28 v3
  2016-12-19  0:26     ` RISC-V Fixes for 2.28 v2 Alan Modra
@ 2016-12-19  4:27       ` Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
                           ` (9 more replies)
  2016-12-19  6:24       ` RISC-V Fixes for 2.28 v2 Cary Coutant
  1 sibling, 10 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

On Sun, 18 Dec 2016 16:26:26 PST (-0800), amodra@gmail.com wrote:
> On Sat, Dec 17, 2016 at 11:00:00PM -0800, Palmer Dabbelt wrote:
>> Here's something that I hope is actually a set of ChangeLog entries this time,
>
> I think that if you had read the link I gave you, you'd know that you
> have not complied with ChangeLog requirements.  So, no, this patchset
> is not ready to commit.  And yes, writing ChangeLogs is tedious.

Sorry, I guess I must have just gotten confused as to what the format was.
I've read the web page again (and read more of the ChangeLog entries in
binutils) and I think I have a proper ChangeLog now.

Sorry for the trouble!

> Some tips: Create the ChangeLog at the same time as you edit the
> source.  Emacs "C-x 4 a" will usually give you a good entry and
> mention the function being edited, which was one of the reasons why
> your entries fail to be OK.  Put the body of the ChangeLog entry in
> the git log, along with a prototype email that will form the basis of
> your eventual mailing list post.  That way there isn't much work left
> to do later, and leaving some sort of description in the git log is a
> really good idea.  Also, this keeps the ChangeLog entry with the patch
> rather than putting it in the email covering letter.  Do mention all
> substantive changes in the ChangeLog, eg. you missed a mention of
> fixing src_mask in the howtos.  For non-substantive changes it's OK to
> just write
>
>       * filename.c: Formatting and comment fixes throughout.
>
> and it's OK when making a change to a function signature to write
>
>       * filename.c (some_func): Add blah parameter, use to decide
>       blahness.  Update all callers.
>
> ie. you don't need to call out secondary details in perhaps dozens of
> functions that need tweaking to pass an extra param to "some_func".
>
> Use
> http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/git-merge-changelog.c
> to help merge your local ChangeLog entries.

Thanks for the tips.  As suggested, I've put the ChangeLog entries into each
patch's git log, they will be sent along with each patch.  I'll try to avoid
screwing this up again in the future.

Thanks for all the help!

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 2/9] Formatting changes for RISC-V
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
                           ` (5 preceding siblings ...)
  2016-12-19  4:27         ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
@ 2016-12-19  4:27         ` Palmer Dabbelt
  2016-12-19  5:58           ` Alan Modra
  2016-12-19  4:27         ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
                           ` (2 subsequent siblings)
  9 siblings, 1 reply; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

This is a mixed bag of format changes:

 * Replacing constants with macros (0xffffffff with MINUS_ONE, for
   example).  There's one technically functional change in here (some
   MINUS_ONEs are changed to 0), but it only changes the behavior of an
   otherwise-unused field.
 * Using 0 instead of 0x0 in the relocation table.
 * There were some missing spaces before parens, the spaces have been
   added.
 * A handful of comments are now more descriptive.
 * A bunch of whitespace-only changes, mostly alignment and brace
   newlines.

bfd/ChangeLog:

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * elxx-riscv.c (howto_table): Change the src_mask field from
        MINUS_ONE to 0 for R_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD64,
        R_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32,
        R_RISCV_TLS_DTPREL64, R_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL64.

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * elfnn-riscv.c: Formatting and comment fixes throughout.
        * elfxx-riscv.c: Likewise.

opcodes/ChangeLog:

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * riscv-opc.c: Put opening braces of array initializers on the
        same line as the array declaration.
        * riscv-opc.c: Add a space before a macro call.

gas/ChangeLog:

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * config/tc-riscv.c: Formatting and comment fixes throughout.
---
 bfd/elfnn-riscv.c     |  4 ++--
 bfd/elfxx-riscv.c     | 38 +++++++++++++++--------------------
 gas/config/tc-riscv.c | 55 ++++++++++++++++++++++++++-------------------------
 opcodes/riscv-opc.c   | 14 ++++++-------
 4 files changed, 52 insertions(+), 59 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 88d5d66..e18bd71 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -220,7 +220,7 @@ riscv_make_plt_entry (bfd_vma got, bfd_vma addr, uint32_t *entry)
      nop */
 
   entry[0] = RISCV_UTYPE (AUIPC, X_T3, RISCV_PCREL_HIGH_PART (got, addr));
-  entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART(got, addr));
+  entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART (got, addr));
   entry[2] = RISCV_ITYPE (JALR, X_T1, X_T3, 0);
   entry[3] = RISCV_NOP;
 }
@@ -2329,7 +2329,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && !(riscv_elf_hash_entry(h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
+      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
     {
       asection *sgot;
       asection *srela;
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index c1f28f7..0fb250d 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -63,7 +63,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_32",			/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
-	 0xffffffff,			/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   /* 64 bit relocation.  */
@@ -93,7 +93,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_RELATIVE",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
-	 0xffffffff,			/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   HOWTO (R_RISCV_COPY,			/* type */
@@ -106,8 +106,8 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_COPY",		/* name */
 	 FALSE,				/* partial_inplace */
-	 0x0,         			/* src_mask */
-	 0x0,		        	/* dst_mask */
+	 0,         			/* src_mask */
+	 0,		        	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   HOWTO (R_RISCV_JUMP_SLOT,		/* type */
@@ -120,8 +120,8 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_JUMP_SLOT",		/* name */
 	 FALSE,				/* partial_inplace */
-	 0x0,         			/* src_mask */
-	 0x0,		        	/* dst_mask */
+	 0,         			/* src_mask */
+	 0,		        	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   /* Dynamic TLS relocations.  */
@@ -135,7 +135,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPMOD32",	/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -149,7 +149,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPMOD64",	/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -163,7 +163,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPREL32",	/* name */
 	 TRUE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -177,7 +177,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPREL64",	/* name */
 	 TRUE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -191,7 +191,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_TPREL32",		/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -205,7 +205,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_TPREL64",		/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -238,9 +238,6 @@ static reloc_howto_type howto_table[] =
 	 TRUE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-					/* This needs complex overflow
-					   detection, because the upper 36
-					   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_JAL",			/* name */
 	 FALSE,				/* partial_inplace */
@@ -264,7 +261,7 @@ static reloc_howto_type howto_table[] =
 					/* dst_mask */
 	 TRUE),				/* pcrel_offset */
 
-  /* 32-bit PC-relative function call (AUIPC/JALR).  */
+  /* Like R_RISCV_CALL, but not locally binding.  */
   HOWTO (R_RISCV_CALL_PLT,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -460,7 +457,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* TLS LE thread pointer usage.  */
+  /* TLS LE thread pointer usage.  May be relaxed.  */
   HOWTO (R_RISCV_TPREL_ADD,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -665,9 +662,6 @@ static reloc_howto_type howto_table[] =
 	 TRUE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-					/* This needs complex overflow
-					   detection, because the upper 36
-					   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_RVC_JUMP",		/* name */
 	 FALSE,				/* partial_inplace */
@@ -690,7 +684,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_RVC_IMM (-1U),		/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* High 12 bits of 32-bit load or add.  */
+  /* GP-relative load.  */
   HOWTO (R_RISCV_GPREL_I,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -705,7 +699,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* High 12 bits of 32-bit store.  */
+  /* GP-relative store.  */
   HOWTO (R_RISCV_GPREL_S,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index b363867..d8a627d 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -28,6 +28,7 @@
 #include "itbl-ops.h"
 #include "dwarf2dbg.h"
 #include "dw2gencfi.h"
+#include "struc-symbol.h"
 
 #include "elf/riscv.h"
 #include "opcode/riscv.h"
@@ -511,29 +512,29 @@ validate_riscv_insn (const struct riscv_opcode *opc)
       case 'C': /* RVC */
 	switch (c = *p++)
 	  {
-	  case 'a': used_bits |= ENCODE_RVC_J_IMM(-1U); break;
+	  case 'a': used_bits |= ENCODE_RVC_J_IMM (-1U); break;
 	  case 'c': break; /* RS1, constrained to equal sp */
 	  case 'i': used_bits |= ENCODE_RVC_SIMM3(-1U); break;
-	  case 'j': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case 'k': used_bits |= ENCODE_RVC_LW_IMM(-1U); break;
-	  case 'l': used_bits |= ENCODE_RVC_LD_IMM(-1U); break;
-	  case 'm': used_bits |= ENCODE_RVC_LWSP_IMM(-1U); break;
-	  case 'n': used_bits |= ENCODE_RVC_LDSP_IMM(-1U); break;
-	  case 'p': used_bits |= ENCODE_RVC_B_IMM(-1U); break;
+	  case 'j': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case 'k': used_bits |= ENCODE_RVC_LW_IMM (-1U); break;
+	  case 'l': used_bits |= ENCODE_RVC_LD_IMM (-1U); break;
+	  case 'm': used_bits |= ENCODE_RVC_LWSP_IMM (-1U); break;
+	  case 'n': used_bits |= ENCODE_RVC_LDSP_IMM (-1U); break;
+	  case 'p': used_bits |= ENCODE_RVC_B_IMM (-1U); break;
 	  case 's': USE_BITS (OP_MASK_CRS1S, OP_SH_CRS1S); break;
 	  case 't': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
-	  case 'u': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case 'v': used_bits |= ENCODE_RVC_IMM(-1U); break;
+	  case 'u': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case 'v': used_bits |= ENCODE_RVC_IMM (-1U); break;
 	  case 'w': break; /* RS1S, constrained to equal RD */
 	  case 'x': break; /* RS2S, constrained to equal RD */
-	  case 'K': used_bits |= ENCODE_RVC_ADDI4SPN_IMM(-1U); break;
-	  case 'L': used_bits |= ENCODE_RVC_ADDI16SP_IMM(-1U); break;
-	  case 'M': used_bits |= ENCODE_RVC_SWSP_IMM(-1U); break;
-	  case 'N': used_bits |= ENCODE_RVC_SDSP_IMM(-1U); break;
+	  case 'K': used_bits |= ENCODE_RVC_ADDI4SPN_IMM (-1U); break;
+	  case 'L': used_bits |= ENCODE_RVC_ADDI16SP_IMM (-1U); break;
+	  case 'M': used_bits |= ENCODE_RVC_SWSP_IMM (-1U); break;
+	  case 'N': used_bits |= ENCODE_RVC_SDSP_IMM (-1U); break;
 	  case 'U': break; /* RS1, constrained to equal RD */
 	  case 'V': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
-	  case '<': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case '>': used_bits |= ENCODE_RVC_IMM(-1U); break;
+	  case '<': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case '>': used_bits |= ENCODE_RVC_IMM (-1U); break;
 	  case 'T': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
 	  case 'D': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
 	  default:
@@ -563,11 +564,11 @@ validate_riscv_insn (const struct riscv_opcode *opc)
       case 'P':	USE_BITS (OP_MASK_PRED,		OP_SH_PRED); break;
       case 'Q':	USE_BITS (OP_MASK_SUCC,		OP_SH_SUCC); break;
       case 'o':
-      case 'j': used_bits |= ENCODE_ITYPE_IMM(-1U); break;
-      case 'a':	used_bits |= ENCODE_UJTYPE_IMM(-1U); break;
-      case 'p':	used_bits |= ENCODE_SBTYPE_IMM(-1U); break;
-      case 'q':	used_bits |= ENCODE_STYPE_IMM(-1U); break;
-      case 'u':	used_bits |= ENCODE_UTYPE_IMM(-1U); break;
+      case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break;
+      case 'a':	used_bits |= ENCODE_UJTYPE_IMM (-1U); break;
+      case 'p':	used_bits |= ENCODE_SBTYPE_IMM (-1U); break;
+      case 'q':	used_bits |= ENCODE_STYPE_IMM (-1U); break;
+      case 'u':	used_bits |= ENCODE_UTYPE_IMM (-1U); break;
       case '[': break;
       case ']': break;
       case '0': break;
@@ -661,7 +662,7 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
     {
       reloc_howto_type *howto;
 
-      gas_assert(address_expr);
+      gas_assert (address_expr);
       if (reloc_type == BFD_RELOC_12_PCREL
 	  || reloc_type == BFD_RELOC_RISCV_JMP)
 	{
@@ -814,7 +815,7 @@ static symbolS *
 make_internal_label (void)
 {
   return (symbolS *) local_symbol_make (FAKE_LABEL_NAME, now_seg,
-					(valueT) frag_now_fix(), frag_now);
+					(valueT) frag_now_fix (), frag_now);
 }
 
 /* Load an entry from the GOT.  */
@@ -874,14 +875,14 @@ load_const (int reg, expressionS *ep)
       return;
     }
 
-  if (xlen > 32 && !IS_SEXT_32BIT_NUM(ep->X_add_number))
+  if (xlen > 32 && !IS_SEXT_32BIT_NUM (ep->X_add_number))
     {
       /* Reduce to a signed 32-bit constant using SLLI and ADDI.  */
       while (((upper.X_add_number >> shift) & 1) == 0)
 	shift++;
 
       upper.X_add_number = (int64_t) upper.X_add_number >> shift;
-      load_const(reg, &upper);
+      load_const (reg, &upper);
 
       macro_build (NULL, "slli", "d,s,>", reg, reg, shift);
       if (lower.X_add_number != 0)
@@ -1469,8 +1470,8 @@ rvc_lui:
 		  my_getExpression (imm_expr, s);
 		  check_absolute_expr (ip, imm_expr);
 		  if ((unsigned long) imm_expr->X_add_number > 0xfff)
-		    as_warn(_("Improper CSR address (%lu)"),
-			    (unsigned long) imm_expr->X_add_number);
+		    as_warn (_("Improper CSR address (%lu)"),
+			     (unsigned long) imm_expr->X_add_number);
 		  INSERT_OPERAND (CSR, *ip, imm_expr->X_add_number);
 		  imm_expr->X_op = O_absent;
 		  s = expr_end;
@@ -2242,7 +2243,7 @@ md_convert_frag_branch (fragS *fragp)
 	    goto done;
 
 	  default:
-	    abort();
+	    abort ();
 	}
     }
 
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 1d8d579..256e089 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -34,8 +34,7 @@ const char * const riscv_gpr_names_numeric[NGPR] =
   "x24",  "x25",  "x26",  "x27",  "x28",  "x29",  "x30",  "x31"
 };
 
-const char * const riscv_gpr_names_abi[NGPR] =
-{
+const char * const riscv_gpr_names_abi[NGPR] = {
   "zero", "ra", "sp",  "gp",  "tp", "t0",  "t1",  "t2",
   "s0",   "s1", "a0",  "a1",  "a2", "a3",  "a4",  "a5",
   "a6",   "a7", "s2",  "s3",  "s4", "s5",  "s6",  "s7",
@@ -50,8 +49,7 @@ const char * const riscv_fpr_names_numeric[NFPR] =
   "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31"
 };
 
-const char * const riscv_fpr_names_abi[NFPR] =
-{
+const char * const riscv_fpr_names_abi[NFPR] = {
   "ft0", "ft1", "ft2",  "ft3",  "ft4", "ft5", "ft6",  "ft7",
   "fs0", "fs1", "fa0",  "fa1",  "fa2", "fa3", "fa4",  "fa5",
   "fa6", "fa7", "fs2",  "fs3",  "fs4", "fs5", "fs6",  "fs7",
@@ -72,9 +70,9 @@ const char * const riscv_fpr_names_abi[NFPR] =
 #define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2)
 #define MASK_RD (OP_MASK_RD << OP_SH_RD)
 #define MASK_CRS2 (OP_MASK_CRS2 << OP_SH_CRS2)
-#define MASK_IMM ENCODE_ITYPE_IMM(-1U)
-#define MASK_RVC_IMM ENCODE_RVC_IMM(-1U)
-#define MASK_UIMM ENCODE_UTYPE_IMM(-1U)
+#define MASK_IMM ENCODE_ITYPE_IMM (-1U)
+#define MASK_RVC_IMM ENCODE_RVC_IMM (-1U)
+#define MASK_UIMM ENCODE_UTYPE_IMM (-1U)
 #define MASK_RM (OP_MASK_RM << OP_SH_RM)
 #define MASK_PRED (OP_MASK_PRED << OP_SH_PRED)
 #define MASK_SUCC (OP_MASK_SUCC << OP_SH_SUCC)
@@ -240,7 +238,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"or",        "I",   "d,s,t",  MATCH_OR, MASK_OR, match_opcode, 0 },
 {"or",        "I",   "d,s,j",  MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS },
 {"auipc",     "I",   "d,u",  MATCH_AUIPC, MASK_AUIPC, match_opcode, 0 },
-{"seqz",      "I",   "d,s",  MATCH_SLTIU | ENCODE_ITYPE_IMM(1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
+{"seqz",      "I",   "d,s",  MATCH_SLTIU | ENCODE_ITYPE_IMM (1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
 {"snez",      "I",   "d,t",  MATCH_SLTU, MASK_SLTU | MASK_RS1, match_opcode, INSN_ALIAS },
 {"sltz",      "I",   "d,s",  MATCH_SLT, MASK_SLT | MASK_RS2, match_opcode, INSN_ALIAS },
 {"sgtz",      "I",   "d,t",  MATCH_SLT, MASK_SLT | MASK_RS1, match_opcode, INSN_ALIAS },
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 4/9] Fix an integer overflow in relocation handling
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
                           ` (4 preceding siblings ...)
  2016-12-19  4:27         ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
@ 2016-12-19  4:27         ` Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
                           ` (3 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

bfd/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * elfnn-riscv.c (bfd_riscv_get_max_alignment): Return bfd_vma
        instead of unsigned int.
        * elfnn-riscv.c (_bfd_riscv_relax_lui): Change the type of
        max_alignment to bfd_vma.
        * elfnn-riscv.c (_bfd_riscv_relax_align): Likewise.
---
 bfd/elfnn-riscv.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 5976118..461bce3 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2759,7 +2759,7 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 
 /* Traverse all output sections and return the max alignment.  */
 
-static unsigned int
+static bfd_vma
 _bfd_riscv_get_max_alignment (asection *sec)
 {
   unsigned int max_alignment_power = 0;
@@ -2771,7 +2771,7 @@ _bfd_riscv_get_max_alignment (asection *sec)
 	max_alignment_power = o->alignment_power;
     }
 
-  return 1 << max_alignment_power;
+  return (bfd_vma) 1 << max_alignment_power;
 }
 
 /* Relax non-PIC global variable references.  */
@@ -2783,7 +2783,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      struct bfd_link_info *link_info,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
-		      unsigned int max_alignment,
+		      bfd_vma max_alignment,
 		      bfd_vma reserve_size,
 		      bfd_boolean *again)
 {
@@ -2900,7 +2900,7 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
-			unsigned int max_alignment ATTRIBUTE_UNUSED,
+			bfd_vma max_alignment ATTRIBUTE_UNUSED,
 			bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			bfd_boolean *again ATTRIBUTE_UNUSED)
 {
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
@ 2016-12-19  4:27         ` Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
                           ` (8 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

sc is a misnomer, because they aren't inherently sc.

opcodes/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * riscv-opc.c (riscv_opcodes): Rename the "*.sc" instructions to
        "*.aqrl".
---
 opcodes/riscv-opc.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 9ea3b8a..3c732fd 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -343,17 +343,17 @@ const struct riscv_opcode riscv_opcodes[] =
 {"amomaxu.w.rl", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_RL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
 {"amomin.w.rl",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_RL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
 {"amominu.w.rl", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_RL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
-{"lr.w.sc",      "A",   "d,0(s)",    MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, 0 },
-{"sc.w.sc",      "A",   "d,t,0(s)",  MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, 0 },
-{"amoadd.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 },
-{"amoswap.w.sc", "A",   "d,t,0(s)",  MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 },
-{"amoand.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 },
-{"amoor.w.sc",   "A",   "d,t,0(s)",  MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 },
-{"amoxor.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 },
-{"amomax.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 },
-{"amomaxu.w.sc", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
-{"amomin.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
-{"amominu.w.sc", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
+{"lr.w.aqrl",    "A",   "d,0(s)",    MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, 0 },
+{"sc.w.aqrl",    "A",   "d,t,0(s)",  MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, 0 },
+{"amoadd.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 },
+{"amoswap.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 },
+{"amoand.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 },
+{"amoor.w.aqrl",   "A",   "d,t,0(s)",  MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 },
+{"amoxor.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 },
+{"amomax.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 },
+{"amomaxu.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
+{"amomin.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
+{"amominu.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
 {"lr.d",         "64A", "d,0(s)",    MATCH_LR_D, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
 {"sc.d",         "64A", "d,t,0(s)",  MATCH_SC_D, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
 {"amoadd.d",     "64A", "d,t,0(s)",  MATCH_AMOADD_D, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
@@ -387,17 +387,17 @@ const struct riscv_opcode riscv_opcodes[] =
 {"amomaxu.d.rl", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_RL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
 {"amomin.d.rl",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_RL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
 {"amominu.d.rl", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_RL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
-{"lr.d.sc",      "64A", "d,0(s)",    MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
-{"sc.d.sc",      "64A", "d,t,0(s)",  MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
-{"amoadd.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
-{"amoswap.d.sc", "64A", "d,t,0(s)",  MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 },
-{"amoand.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 },
-{"amoor.d.sc",   "64A", "d,t,0(s)",  MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 },
-{"amoxor.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 },
-{"amomax.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 },
-{"amomaxu.d.sc", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
-{"amomin.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
-{"amominu.d.sc", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
+{"lr.d.aqrl",    "64A", "d,0(s)",    MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
+{"sc.d.aqrl",    "64A", "d,t,0(s)",  MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
+{"amoadd.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
+{"amoswap.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 },
+{"amoand.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 },
+{"amoor.d.aqrl",   "64A", "d,t,0(s)",  MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 },
+{"amoxor.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 },
+{"amomax.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 },
+{"amomaxu.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
+{"amomin.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
+{"amominu.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
 
 /* Multiply/Divide instruction subset */
 {"mul",       "M",   "d,s,t",  MATCH_MUL, MASK_MUL, match_opcode, 0 },
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
                           ` (7 preceding siblings ...)
  2016-12-19  4:27         ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
@ 2016-12-19  4:27         ` Palmer Dabbelt
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

We've decided to standardize on two flags for RISC-V: "-march" sets the
target architecture (which determines which instructions can be
generated), and "-mabi" sets the target ABI.  We needed to rework this
because the old flag set didn't support soft-float or single-float ABIs,
and didn't support an x32-style ABI on RISC-V.

Additionally, we've changed the behavior of the -march flag: it's now a
lot stricter and only parses things we can actually understand.
Additionally, it's now lowercase-only: the rationale is that while the
RISC-V ISA manual specifies that ISA strings are case-insensitive, in
Linux-land things are usually case-sensitive.  Since this flag can be
used to determine library paths, we didn't want to bake some
case-insensitivity in there that would case trouble later.

This patch implements these two new flags and removes the old flags that
could conflict with these.  There wasn't a RISC-V release before, so we
want to just support a clean flag set.

bfd/ChangeLog

2016-12-14 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.

binutils/ChangeLog

2016-12-14 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.

gas/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * config/tc-riscv.c (xlen): No longer used externally.
        * config/tc-riscv.h (xlen): Likewise.
        * config/tc-riscv.c (abi_xlen): New variable, holds the length
        of X-registers as used by the ABI.
        * config/tc-riscv.c (options): Replace
        OPTION_{M32,M64,MSOFT_FLOAT,MHARD_FLOAT,MRVC} with OPTION_MABI.
        * config/tc-riscv.c (md_longopts): Likewise.
        * config/tc-riscv.c (md_parse_option): Likewise.
        * config/tc-riscv.c (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.
        * config/tc-riscv.c (float_abi): New type, specifies the
        floating-point ABI.
        * config/tc-riscv.c (riscv_set_abi): New function.

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * config/tc-riscv.c (riscv_add_subset): Only allow lower-case
        ISA names and require them to start with "rv".
        * config/tc-riscv.c (riscv_after_parse_args): Likewise.

opcodes/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * riscv-dis.c (riscv_disassemble_insn): Default to the ELF's
        XLEN when none is provided.
---
 bfd/elfnn-riscv.c     |   4 +-
 binutils/readelf.c    |  21 +++++-
 gas/config/tc-riscv.c | 197 ++++++++++++++++++++++++--------------------------
 gas/config/tc-riscv.h |   1 -
 gas/doc/as.texinfo    |   5 +-
 gas/doc/c-riscv.texi  |  23 ++----
 include/elf/riscv.h   |  16 +++-
 opcodes/riscv-dis.c   |   8 +-
 8 files changed, 144 insertions(+), 131 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 461bce3..d76163e 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/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/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/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/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;
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 6/9] Don't define our own .p2align
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
                           ` (2 preceding siblings ...)
  2016-12-19  4:27         ` [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases Palmer Dabbelt
@ 2016-12-19  4:27         ` Palmer Dabbelt
  2016-12-19  4:27         ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
                           ` (5 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  4:27 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

gas/ChangeLog

2015-12-14 Andrew Waterman <andrew@sifive.com>

        * config/tc-riscv.c (riscv_pseudo_table): Removed "align",
        "p2align", and "balign".
        * config/tc-riscv.c (s_align): Removed.
        * config/tc-riscv.h (riscv_haddle_align): New function.
        * config/tc-riscv.c (riscv_handle_align): Likewise.
        * config/tc-riscv.h (riscv_frag_align_code): Likewise.
        * config/tc-riscv.c (riscv_frag_align_code): Likewise.
        * config/tc-riscv.h (riscv_make_nops): Likewise.
        * config/tc-riscv.c (riscv_make_nops): Likewise.
        * config/tc-riscv.h (MAX_MEM_FOR_RS_ALIGN_CODE): Changed to 7.
        * config/tc-riscv.h (HANDLE_ALIGN): New define.
        * config/tc-riscv.h (md_do_align): New define.
---
 gas/config/tc-riscv.c | 96 ++++++++++++++++++++++++++++++---------------------
 gas/config/tc-riscv.h | 14 ++++++--
 2 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 77c92cf..2d953c5 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2185,63 +2185,82 @@ s_bss (int ignore ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
-/* Align to a given power of two.  */
-
 static void
-s_align (int bytes_p)
+riscv_make_nops (char *buf, bfd_vma bytes)
 {
-  int fill_value = 0, fill_value_specified = 0;
-  int min_text_alignment = riscv_opts.rvc ? 2 : 4;
-  int alignment = get_absolute_expression(), bytes;
+  bfd_vma i = 0;
 
-  if (bytes_p)
+  if (bytes % 4 == 2)
     {
-      bytes = alignment;
-      if (bytes < 1 || (bytes & (bytes-1)) != 0)
-	as_bad (_("alignment not a power of 2: %d"), bytes);
-      for (alignment = 0; bytes > 1; bytes >>= 1)
-	alignment++;
+      md_number_to_chars (buf, RVC_NOP, 2);
+      i += 2;
     }
 
-  bytes = 1 << alignment;
+  gas_assert ((bytes - i) % 4 == 0);
 
-  if (alignment < 0 || alignment > 31)
-    as_bad (_("unsatisfiable alignment: %d"), alignment);
+  for ( ; i < bytes; i += 4)
+    md_number_to_chars (buf + i, RISCV_NOP, 4);
+}
 
-  if (*input_line_pointer == ',')
-    {
-      ++input_line_pointer;
-      fill_value = get_absolute_expression ();
-      fill_value_specified = 1;
-    }
+/* Called from md_do_align.  Used to create an alignment frag in a
+   code section by emitting a worst-case NOP sequence that the linker
+   will later relax to the correct number of NOPs.  We can't compute
+   the correct alignment now because of other linker relaxations.  */
+
+bfd_boolean
+riscv_frag_align_code (int n)
+{
+  bfd_vma bytes = (bfd_vma)1 << n;
+  bfd_vma min_text_alignment = riscv_opts.rvc ? 2 : 4;
+
+  /* When not relaxing, riscv_handle_align handles code alignment.  */
+  if (!riscv_opts.relax)
+    return FALSE;
 
-  if (!fill_value_specified
-      && subseg_text_p (now_seg)
-      && bytes > min_text_alignment)
+  if (bytes > min_text_alignment)
     {
-      /* Emit the worst-case NOP string.  The linker will delete any
-	 unnecessary NOPs.  This allows us to support code alignment
-	 in spite of linker relaxations.  */
-      bfd_vma i, worst_case_bytes = bytes - min_text_alignment;
+      bfd_vma worst_case_bytes = bytes - min_text_alignment;
       char *nops = frag_more (worst_case_bytes);
-      for (i = 0; i < worst_case_bytes - 2; i += 4)
-	md_number_to_chars (nops + i, RISCV_NOP, 4);
-      if (i < worst_case_bytes)
-	md_number_to_chars (nops + i, RVC_NOP, 2);
-
       expressionS ex;
+
       ex.X_op = O_constant;
       ex.X_add_number = worst_case_bytes;
 
+      riscv_make_nops (nops, worst_case_bytes);
+
       fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
 		   &ex, FALSE, BFD_RELOC_RISCV_ALIGN);
     }
-  else if (alignment)
-    frag_align (alignment, fill_value, 0);
 
-  record_alignment (now_seg, alignment);
+  return TRUE;
+}
 
-  demand_empty_rest_of_line ();
+/* Implement HANDLE_ALIGN.  */
+
+void
+riscv_handle_align (fragS *fragP)
+{
+  switch (fragP->fr_type)
+    {
+    case rs_align_code:
+      /* When relaxing, riscv_frag_align_code handles code alignment.  */
+      if (!riscv_opts.relax)
+	{
+	  bfd_signed_vma count = fragP->fr_next->fr_address
+				 - fragP->fr_address - fragP->fr_fix;
+
+	  if (count <= 0)
+	    break;
+
+	  count &= MAX_MEM_FOR_RS_ALIGN_CODE;
+	  riscv_make_nops (fragP->fr_literal + fragP->fr_fix, count);
+	  fragP->fr_var = count;
+	}
+      break;
+
+    default:
+      break;
+    }
 }
 
 int
@@ -2488,9 +2507,6 @@ static const pseudo_typeS riscv_pseudo_table[] =
   {"dtprelword", s_dtprel, 4},
   {"dtpreldword", s_dtprel, 8},
   {"bss", s_bss, 0},
-  {"align", s_align, 0},
-  {"p2align", s_align, 0},
-  {"balign", s_align, 1},
   {"uleb128", s_riscv_leb128, 0},
   {"sleb128", s_riscv_leb128, 1},
 
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 5e07fda..5d6b83f 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -48,8 +48,18 @@ extern int riscv_relax_frag (asection *, struct frag *, long);
 #define md_undefined_symbol(name)	(0)
 #define md_operand(x)
 
-/* FIXME: it is unclear if this is used, or if it is even correct.  */
-#define MAX_MEM_FOR_RS_ALIGN_CODE  (1 + 2)
+extern bfd_boolean riscv_frag_align_code (int);
+#define md_do_align(N, FILL, LEN, MAX, LABEL)				\
+  if ((N) != 0 && !(FILL) && !need_pass_2 && subseg_text_p (now_seg))	\
+    {									\
+      if (riscv_frag_align_code (N))					\
+	goto LABEL;							\
+    }
+
+extern void riscv_handle_align (fragS *);
+#define HANDLE_ALIGN riscv_handle_align
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE 7
 
 /* The ISA of the target may change based on command-line arguments.  */
 #define TARGET_FORMAT riscv_target_format()
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 2/9] Formatting changes for RISC-V
  2016-12-19  4:27         ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
@ 2016-12-19  5:58           ` Alan Modra
  2016-12-19  6:29             ` Palmer Dabbelt
  0 siblings, 1 reply; 57+ messages in thread
From: Alan Modra @ 2016-12-19  5:58 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils, Andrew Waterman

On Sun, Dec 18, 2016 at 08:27:04PM -0800, Palmer Dabbelt wrote:
>         * riscv-opc.c: Put opening braces of array initializers on the
>         same line as the array declaration.
>         * riscv-opc.c: Add a space before a macro call.

Omit repeating the file name on the second line.  Or just

	* riscv-opc.c: Formatting fixes.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 3/9] Rework RISC-V relocations
  2016-12-19  4:27         ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
@ 2016-12-19  6:10           ` Alan Modra
  0 siblings, 0 replies; 57+ messages in thread
From: Alan Modra @ 2016-12-19  6:10 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils, Andrew Waterman

On Sun, Dec 18, 2016 at 08:27:05PM -0800, Palmer Dabbelt wrote:
> 2016-12-14 Andrew Waterman <andrew@sifive.com>
>            Kuan-Lin Chen <kuanlinchentw@gmail.com>
> 
>         * reloc.c (BFD_RELOC_RISCV_TPREL_I): New relocation.
>         * reloc.c (BFD_RELOC_RISCV_TPREL_S): Likewise.
>         * reloc.c (BFD_RELOC_RISCV_RELAX): Likewise.
>         * reloc.c (BFD_RELOC_RISCV_CFA): Likewise.
>         * reloc.c (BFD_RELOC_RISCV_SUB6): Likewise.
>         * reloc.c (BFD_RELOC_RISCV_SET8): Likewise.
>         * reloc.c (BFD_RELOC_RISCV_SET8): Likewise.
>         * reloc.c (BFD_RELOC_RISCV_SET16): Likewise.
>         * reloc.c (BFD_RELOC_RISCV_SET32): Likewise.

Omit repeating the file name.

>         * bfd-in2.h: Regenerate.
>         * libbfd.h: Likewise.
>         * elfnn-riscv.c (perform_relocation): Handle the new
>         relocations.
>         * elfnn-riscv.c (_bfd_riscv_relax_tls_le): Likewise.
>         * elfnn-riscv.c (_bfd_riscv_relax_align): Likewise.
>         * elfnn-riscv.c (_bfd_riscv_relax_section): Likewise.
>         * elfnn-riscv.c (howto_table): Likewise.
>         * elfnn-riscv.c (riscv_reloc_map): Likewise.

Similarly, and merge below with above.  If there is reason to separate
into two ChangeLog entries, then separate the patch too.

> 2016-12-14 Andrew Waterman <andrew@sifive.com>
>            Kuan-Lin Chen <kuanlinchentw@gmail.com>
> 
>         * elfnn-riscv.c (relax_func_t): New type.
>         * elfnn-riscv.c (_bfd_riscv_relax_call): Add reserve_size
>         argument, which controls the maximal offset pessimism.
>         * elfnn-riscv.c (_bfd_riscv_relax_lui): Likewise.
>         * elfnn-riscv.c (_bfd_riscv_relax_tls_le): Likewise.
>         * elfnn-riscv.c (_bfd_riscv_relax_align): Likewise.
>         * elfnn-riscv.c (_bfd_riscv_relax_section): Compute the required
>         reserve size when relocating and use it to when calling
>         relax_func.
> 
> gas/ChangeLog
> 
> 2016-12-14 Andrew Waterman <andrew@sifive.com>
>            Kuan-Lin Chen <kuanlinchentw@gmail.com>
> 
>         * config/tc-riscv.c (riscv_set_options): Add relax.
>         * config/tc-riscv.c (riscv_opts): Likewise.
>         * config/tc-riscv.c (s_riscv_option): Add relax and norelax.
>         * config/tc-riscv.c (riscv_apply_const_reloc): New function.
>         * config/tc-riscv.c (append_insn): Move constant relocation
>         handling to riscv_apply_const_reloc.
>         * config/tc-riscv.c (md_pcrel_from): Likewise.
>         * config/tc-riscv.c (parse_relocation): Skip BFD_RELOC_UNUSED.
>         * config/tc-riscv.c (md_pcrel_from): Handle
>         BFD_RELOC_RISCV_SUB6, BFD_RELOC_RISCV_RELAX,
>         BFD_RELOC_RISCV_CFA.
>         * config/tc-riscv.c (md_apply_fix): Likewise.
>         * config/tc-riscv.c (riscv_pre_output_hook): New function.
>         * config/tc-riscv.h (md_pre_output_hook): Use
>         riscv_pre_output_hook.
>         * config/tc-riscv.h (DWARF_CIE_DATA_ALIGNMENT): Always -4.

Again, don't repeat file name.  Same comment applies to following
patches, but otherwise looks reasonable.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: RISC-V Fixes for 2.28 v2
  2016-12-19  0:26     ` RISC-V Fixes for 2.28 v2 Alan Modra
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
@ 2016-12-19  6:24       ` Cary Coutant
  1 sibling, 0 replies; 57+ messages in thread
From: Cary Coutant @ 2016-12-19  6:24 UTC (permalink / raw)
  To: Alan Modra; +Cc: Palmer Dabbelt, Binutils, Mike Frysinger, Andrew Waterman

> Some tips: Create the ChangeLog at the same time as you edit the
> source.

And if you didn't do that, take a look at the "mklog" script in the
contrib directory of the gcc tree. The result isn't perfect, but it
gives you a pretty good start. Just run "git diff" and save the output
to a file, then run mklog on that file, and it'll add a skeleton
ChangeLog to the top of the file.

-cary

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [PATCH 2/9] Formatting changes for RISC-V
  2016-12-19  5:58           ` Alan Modra
@ 2016-12-19  6:29             ` Palmer Dabbelt
  0 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:29 UTC (permalink / raw)
  To: amodra; +Cc: binutils, Andrew Waterman

On Sun, 18 Dec 2016 21:58:19 PST (-0800), amodra@gmail.com wrote:
> On Sun, Dec 18, 2016 at 08:27:04PM -0800, Palmer Dabbelt wrote:
>>         * riscv-opc.c: Put opening braces of array initializers on the
>>         same line as the array declaration.
>>         * riscv-opc.c: Add a space before a macro call.
>
> Omit repeating the file name on the second line.  Or just
>
> 	* riscv-opc.c: Formatting fixes.

OK, I'll use the shorter version.  Since squashing the file names will change
the text of every ChangeLog, I will submit a v4 of the patch set with the
updated ChangeLogs.

Thanks!

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 2/9] Formatting changes for RISC-V
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
@ 2016-12-19  6:54           ` Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
                             ` (7 subsequent siblings)
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:54 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

This is a mixed bag of format changes:

 * Replacing constants with macros (0xffffffff with MINUS_ONE, for
   example).  There's one technically functional change in here (some
   MINUS_ONEs are changed to 0), but it only changes the behavior of an
   otherwise-unused field.
 * Using 0 instead of 0x0 in the relocation table.
 * There were some missing spaces before parens, the spaces have been
   added.
 * A handful of comments are now more descriptive.
 * A bunch of whitespace-only changes, mostly alignment and brace
   newlines.

bfd/ChangeLog:

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * elxx-riscv.c (howto_table): Change the src_mask field from
        MINUS_ONE to 0 for R_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD64,
        R_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32,
        R_RISCV_TLS_DTPREL64, R_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL64.
        * elfnn-riscv.c: Formatting and comment fixes throughout.
        * elfxx-riscv.c: Likewise.

opcodes/ChangeLog:

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * riscv-opc.c: Formatting fixes.

gas/ChangeLog:

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * config/tc-riscv.c: Formatting and comment fixes throughout.
---
 bfd/elfnn-riscv.c     |  4 ++--
 bfd/elfxx-riscv.c     | 38 +++++++++++++++--------------------
 gas/config/tc-riscv.c | 55 ++++++++++++++++++++++++++-------------------------
 opcodes/riscv-opc.c   | 14 ++++++-------
 4 files changed, 52 insertions(+), 59 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 88d5d66..e18bd71 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -220,7 +220,7 @@ riscv_make_plt_entry (bfd_vma got, bfd_vma addr, uint32_t *entry)
      nop */
 
   entry[0] = RISCV_UTYPE (AUIPC, X_T3, RISCV_PCREL_HIGH_PART (got, addr));
-  entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART(got, addr));
+  entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART (got, addr));
   entry[2] = RISCV_ITYPE (JALR, X_T1, X_T3, 0);
   entry[3] = RISCV_NOP;
 }
@@ -2329,7 +2329,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   if (h->got.offset != (bfd_vma) -1
-      && !(riscv_elf_hash_entry(h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
+      && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
     {
       asection *sgot;
       asection *srela;
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index c1f28f7..0fb250d 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -63,7 +63,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_32",			/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
-	 0xffffffff,			/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   /* 64 bit relocation.  */
@@ -93,7 +93,7 @@ static reloc_howto_type howto_table[] =
 	 "R_RISCV_RELATIVE",		/* name */
 	 FALSE,				/* partial_inplace */
 	 0,				/* src_mask */
-	 0xffffffff,			/* dst_mask */
+	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   HOWTO (R_RISCV_COPY,			/* type */
@@ -106,8 +106,8 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_COPY",		/* name */
 	 FALSE,				/* partial_inplace */
-	 0x0,         			/* src_mask */
-	 0x0,		        	/* dst_mask */
+	 0,         			/* src_mask */
+	 0,		        	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   HOWTO (R_RISCV_JUMP_SLOT,		/* type */
@@ -120,8 +120,8 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_JUMP_SLOT",		/* name */
 	 FALSE,				/* partial_inplace */
-	 0x0,         			/* src_mask */
-	 0x0,		        	/* dst_mask */
+	 0,         			/* src_mask */
+	 0,		        	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
   /* Dynamic TLS relocations.  */
@@ -135,7 +135,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPMOD32",	/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -149,7 +149,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPMOD64",	/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -163,7 +163,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPREL32",	/* name */
 	 TRUE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -177,7 +177,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_DTPREL64",	/* name */
 	 TRUE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -191,7 +191,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_TPREL32",		/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -205,7 +205,7 @@ static reloc_howto_type howto_table[] =
 	 bfd_elf_generic_reloc, 	/* special_function */
 	 "R_RISCV_TLS_TPREL64",		/* name */
 	 FALSE,				/* partial_inplace */
-	 MINUS_ONE,			/* src_mask */
+	 0,				/* src_mask */
 	 MINUS_ONE,			/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
@@ -238,9 +238,6 @@ static reloc_howto_type howto_table[] =
 	 TRUE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-					/* This needs complex overflow
-					   detection, because the upper 36
-					   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_JAL",			/* name */
 	 FALSE,				/* partial_inplace */
@@ -264,7 +261,7 @@ static reloc_howto_type howto_table[] =
 					/* dst_mask */
 	 TRUE),				/* pcrel_offset */
 
-  /* 32-bit PC-relative function call (AUIPC/JALR).  */
+  /* Like R_RISCV_CALL, but not locally binding.  */
   HOWTO (R_RISCV_CALL_PLT,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -460,7 +457,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* TLS LE thread pointer usage.  */
+  /* TLS LE thread pointer usage.  May be relaxed.  */
   HOWTO (R_RISCV_TPREL_ADD,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -665,9 +662,6 @@ static reloc_howto_type howto_table[] =
 	 TRUE,				/* pc_relative */
 	 0,				/* bitpos */
 	 complain_overflow_dont,	/* complain_on_overflow */
-					/* This needs complex overflow
-					   detection, because the upper 36
-					   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,		/* special_function */
 	 "R_RISCV_RVC_JUMP",		/* name */
 	 FALSE,				/* partial_inplace */
@@ -690,7 +684,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_RVC_IMM (-1U),		/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* High 12 bits of 32-bit load or add.  */
+  /* GP-relative load.  */
   HOWTO (R_RISCV_GPREL_I,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
@@ -705,7 +699,7 @@ static reloc_howto_type howto_table[] =
 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
 
-  /* High 12 bits of 32-bit store.  */
+  /* GP-relative store.  */
   HOWTO (R_RISCV_GPREL_S,		/* type */
 	 0,				/* rightshift */
 	 2,				/* size */
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index b363867..d8a627d 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -28,6 +28,7 @@
 #include "itbl-ops.h"
 #include "dwarf2dbg.h"
 #include "dw2gencfi.h"
+#include "struc-symbol.h"
 
 #include "elf/riscv.h"
 #include "opcode/riscv.h"
@@ -511,29 +512,29 @@ validate_riscv_insn (const struct riscv_opcode *opc)
       case 'C': /* RVC */
 	switch (c = *p++)
 	  {
-	  case 'a': used_bits |= ENCODE_RVC_J_IMM(-1U); break;
+	  case 'a': used_bits |= ENCODE_RVC_J_IMM (-1U); break;
 	  case 'c': break; /* RS1, constrained to equal sp */
 	  case 'i': used_bits |= ENCODE_RVC_SIMM3(-1U); break;
-	  case 'j': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case 'k': used_bits |= ENCODE_RVC_LW_IMM(-1U); break;
-	  case 'l': used_bits |= ENCODE_RVC_LD_IMM(-1U); break;
-	  case 'm': used_bits |= ENCODE_RVC_LWSP_IMM(-1U); break;
-	  case 'n': used_bits |= ENCODE_RVC_LDSP_IMM(-1U); break;
-	  case 'p': used_bits |= ENCODE_RVC_B_IMM(-1U); break;
+	  case 'j': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case 'k': used_bits |= ENCODE_RVC_LW_IMM (-1U); break;
+	  case 'l': used_bits |= ENCODE_RVC_LD_IMM (-1U); break;
+	  case 'm': used_bits |= ENCODE_RVC_LWSP_IMM (-1U); break;
+	  case 'n': used_bits |= ENCODE_RVC_LDSP_IMM (-1U); break;
+	  case 'p': used_bits |= ENCODE_RVC_B_IMM (-1U); break;
 	  case 's': USE_BITS (OP_MASK_CRS1S, OP_SH_CRS1S); break;
 	  case 't': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
-	  case 'u': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case 'v': used_bits |= ENCODE_RVC_IMM(-1U); break;
+	  case 'u': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case 'v': used_bits |= ENCODE_RVC_IMM (-1U); break;
 	  case 'w': break; /* RS1S, constrained to equal RD */
 	  case 'x': break; /* RS2S, constrained to equal RD */
-	  case 'K': used_bits |= ENCODE_RVC_ADDI4SPN_IMM(-1U); break;
-	  case 'L': used_bits |= ENCODE_RVC_ADDI16SP_IMM(-1U); break;
-	  case 'M': used_bits |= ENCODE_RVC_SWSP_IMM(-1U); break;
-	  case 'N': used_bits |= ENCODE_RVC_SDSP_IMM(-1U); break;
+	  case 'K': used_bits |= ENCODE_RVC_ADDI4SPN_IMM (-1U); break;
+	  case 'L': used_bits |= ENCODE_RVC_ADDI16SP_IMM (-1U); break;
+	  case 'M': used_bits |= ENCODE_RVC_SWSP_IMM (-1U); break;
+	  case 'N': used_bits |= ENCODE_RVC_SDSP_IMM (-1U); break;
 	  case 'U': break; /* RS1, constrained to equal RD */
 	  case 'V': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
-	  case '<': used_bits |= ENCODE_RVC_IMM(-1U); break;
-	  case '>': used_bits |= ENCODE_RVC_IMM(-1U); break;
+	  case '<': used_bits |= ENCODE_RVC_IMM (-1U); break;
+	  case '>': used_bits |= ENCODE_RVC_IMM (-1U); break;
 	  case 'T': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
 	  case 'D': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
 	  default:
@@ -563,11 +564,11 @@ validate_riscv_insn (const struct riscv_opcode *opc)
       case 'P':	USE_BITS (OP_MASK_PRED,		OP_SH_PRED); break;
       case 'Q':	USE_BITS (OP_MASK_SUCC,		OP_SH_SUCC); break;
       case 'o':
-      case 'j': used_bits |= ENCODE_ITYPE_IMM(-1U); break;
-      case 'a':	used_bits |= ENCODE_UJTYPE_IMM(-1U); break;
-      case 'p':	used_bits |= ENCODE_SBTYPE_IMM(-1U); break;
-      case 'q':	used_bits |= ENCODE_STYPE_IMM(-1U); break;
-      case 'u':	used_bits |= ENCODE_UTYPE_IMM(-1U); break;
+      case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break;
+      case 'a':	used_bits |= ENCODE_UJTYPE_IMM (-1U); break;
+      case 'p':	used_bits |= ENCODE_SBTYPE_IMM (-1U); break;
+      case 'q':	used_bits |= ENCODE_STYPE_IMM (-1U); break;
+      case 'u':	used_bits |= ENCODE_UTYPE_IMM (-1U); break;
       case '[': break;
       case ']': break;
       case '0': break;
@@ -661,7 +662,7 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
     {
       reloc_howto_type *howto;
 
-      gas_assert(address_expr);
+      gas_assert (address_expr);
       if (reloc_type == BFD_RELOC_12_PCREL
 	  || reloc_type == BFD_RELOC_RISCV_JMP)
 	{
@@ -814,7 +815,7 @@ static symbolS *
 make_internal_label (void)
 {
   return (symbolS *) local_symbol_make (FAKE_LABEL_NAME, now_seg,
-					(valueT) frag_now_fix(), frag_now);
+					(valueT) frag_now_fix (), frag_now);
 }
 
 /* Load an entry from the GOT.  */
@@ -874,14 +875,14 @@ load_const (int reg, expressionS *ep)
       return;
     }
 
-  if (xlen > 32 && !IS_SEXT_32BIT_NUM(ep->X_add_number))
+  if (xlen > 32 && !IS_SEXT_32BIT_NUM (ep->X_add_number))
     {
       /* Reduce to a signed 32-bit constant using SLLI and ADDI.  */
       while (((upper.X_add_number >> shift) & 1) == 0)
 	shift++;
 
       upper.X_add_number = (int64_t) upper.X_add_number >> shift;
-      load_const(reg, &upper);
+      load_const (reg, &upper);
 
       macro_build (NULL, "slli", "d,s,>", reg, reg, shift);
       if (lower.X_add_number != 0)
@@ -1469,8 +1470,8 @@ rvc_lui:
 		  my_getExpression (imm_expr, s);
 		  check_absolute_expr (ip, imm_expr);
 		  if ((unsigned long) imm_expr->X_add_number > 0xfff)
-		    as_warn(_("Improper CSR address (%lu)"),
-			    (unsigned long) imm_expr->X_add_number);
+		    as_warn (_("Improper CSR address (%lu)"),
+			     (unsigned long) imm_expr->X_add_number);
 		  INSERT_OPERAND (CSR, *ip, imm_expr->X_add_number);
 		  imm_expr->X_op = O_absent;
 		  s = expr_end;
@@ -2242,7 +2243,7 @@ md_convert_frag_branch (fragS *fragp)
 	    goto done;
 
 	  default:
-	    abort();
+	    abort ();
 	}
     }
 
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 1d8d579..256e089 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -34,8 +34,7 @@ const char * const riscv_gpr_names_numeric[NGPR] =
   "x24",  "x25",  "x26",  "x27",  "x28",  "x29",  "x30",  "x31"
 };
 
-const char * const riscv_gpr_names_abi[NGPR] =
-{
+const char * const riscv_gpr_names_abi[NGPR] = {
   "zero", "ra", "sp",  "gp",  "tp", "t0",  "t1",  "t2",
   "s0",   "s1", "a0",  "a1",  "a2", "a3",  "a4",  "a5",
   "a6",   "a7", "s2",  "s3",  "s4", "s5",  "s6",  "s7",
@@ -50,8 +49,7 @@ const char * const riscv_fpr_names_numeric[NFPR] =
   "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31"
 };
 
-const char * const riscv_fpr_names_abi[NFPR] =
-{
+const char * const riscv_fpr_names_abi[NFPR] = {
   "ft0", "ft1", "ft2",  "ft3",  "ft4", "ft5", "ft6",  "ft7",
   "fs0", "fs1", "fa0",  "fa1",  "fa2", "fa3", "fa4",  "fa5",
   "fa6", "fa7", "fs2",  "fs3",  "fs4", "fs5", "fs6",  "fs7",
@@ -72,9 +70,9 @@ const char * const riscv_fpr_names_abi[NFPR] =
 #define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2)
 #define MASK_RD (OP_MASK_RD << OP_SH_RD)
 #define MASK_CRS2 (OP_MASK_CRS2 << OP_SH_CRS2)
-#define MASK_IMM ENCODE_ITYPE_IMM(-1U)
-#define MASK_RVC_IMM ENCODE_RVC_IMM(-1U)
-#define MASK_UIMM ENCODE_UTYPE_IMM(-1U)
+#define MASK_IMM ENCODE_ITYPE_IMM (-1U)
+#define MASK_RVC_IMM ENCODE_RVC_IMM (-1U)
+#define MASK_UIMM ENCODE_UTYPE_IMM (-1U)
 #define MASK_RM (OP_MASK_RM << OP_SH_RM)
 #define MASK_PRED (OP_MASK_PRED << OP_SH_PRED)
 #define MASK_SUCC (OP_MASK_SUCC << OP_SH_SUCC)
@@ -240,7 +238,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"or",        "I",   "d,s,t",  MATCH_OR, MASK_OR, match_opcode, 0 },
 {"or",        "I",   "d,s,j",  MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS },
 {"auipc",     "I",   "d,u",  MATCH_AUIPC, MASK_AUIPC, match_opcode, 0 },
-{"seqz",      "I",   "d,s",  MATCH_SLTIU | ENCODE_ITYPE_IMM(1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
+{"seqz",      "I",   "d,s",  MATCH_SLTIU | ENCODE_ITYPE_IMM (1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
 {"snez",      "I",   "d,t",  MATCH_SLTU, MASK_SLTU | MASK_RS1, match_opcode, INSN_ALIAS },
 {"sltz",      "I",   "d,s",  MATCH_SLT, MASK_SLT | MASK_RS2, match_opcode, INSN_ALIAS },
 {"sgtz",      "I",   "d,t",  MATCH_SLT, MASK_SLT | MASK_RS1, match_opcode, INSN_ALIAS },
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
@ 2016-12-19  6:54           ` Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
                             ` (6 subsequent siblings)
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:54 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

sc is a misnomer, because they aren't inherently sc.

opcodes/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * riscv-opc.c (riscv_opcodes): Rename the "*.sc" instructions to
        "*.aqrl".
---
 opcodes/riscv-opc.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 9ea3b8a..3c732fd 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -343,17 +343,17 @@ const struct riscv_opcode riscv_opcodes[] =
 {"amomaxu.w.rl", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_RL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
 {"amomin.w.rl",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_RL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
 {"amominu.w.rl", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_RL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
-{"lr.w.sc",      "A",   "d,0(s)",    MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, 0 },
-{"sc.w.sc",      "A",   "d,t,0(s)",  MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, 0 },
-{"amoadd.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 },
-{"amoswap.w.sc", "A",   "d,t,0(s)",  MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 },
-{"amoand.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 },
-{"amoor.w.sc",   "A",   "d,t,0(s)",  MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 },
-{"amoxor.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 },
-{"amomax.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 },
-{"amomaxu.w.sc", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
-{"amomin.w.sc",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
-{"amominu.w.sc", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
+{"lr.w.aqrl",    "A",   "d,0(s)",    MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, 0 },
+{"sc.w.aqrl",    "A",   "d,t,0(s)",  MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, 0 },
+{"amoadd.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, 0 },
+{"amoswap.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, 0 },
+{"amoand.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, 0 },
+{"amoor.w.aqrl",   "A",   "d,t,0(s)",  MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, 0 },
+{"amoxor.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, 0 },
+{"amomax.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, 0 },
+{"amomaxu.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, 0 },
+{"amomin.w.aqrl",  "A",   "d,t,0(s)",  MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, 0 },
+{"amominu.w.aqrl", "A",   "d,t,0(s)",  MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, 0 },
 {"lr.d",         "64A", "d,0(s)",    MATCH_LR_D, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
 {"sc.d",         "64A", "d,t,0(s)",  MATCH_SC_D, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
 {"amoadd.d",     "64A", "d,t,0(s)",  MATCH_AMOADD_D, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
@@ -387,17 +387,17 @@ const struct riscv_opcode riscv_opcodes[] =
 {"amomaxu.d.rl", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_RL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
 {"amomin.d.rl",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_RL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
 {"amominu.d.rl", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_RL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
-{"lr.d.sc",      "64A", "d,0(s)",    MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
-{"sc.d.sc",      "64A", "d,t,0(s)",  MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
-{"amoadd.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
-{"amoswap.d.sc", "64A", "d,t,0(s)",  MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 },
-{"amoand.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 },
-{"amoor.d.sc",   "64A", "d,t,0(s)",  MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 },
-{"amoxor.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 },
-{"amomax.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 },
-{"amomaxu.d.sc", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
-{"amomin.d.sc",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
-{"amominu.d.sc", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
+{"lr.d.aqrl",    "64A", "d,0(s)",    MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, 0 },
+{"sc.d.aqrl",    "64A", "d,t,0(s)",  MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, 0 },
+{"amoadd.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, 0 },
+{"amoswap.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, 0 },
+{"amoand.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, 0 },
+{"amoor.d.aqrl",   "64A", "d,t,0(s)",  MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, 0 },
+{"amoxor.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, 0 },
+{"amomax.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, 0 },
+{"amomaxu.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, 0 },
+{"amomin.d.aqrl",  "64A", "d,t,0(s)",  MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, 0 },
+{"amominu.d.aqrl", "64A", "d,t,0(s)",  MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, 0 },
 
 /* Multiply/Divide instruction subset */
 {"mul",       "M",   "d,s,t",  MATCH_MUL, MASK_MUL, match_opcode, 0 },
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
                             ` (4 preceding siblings ...)
  2016-12-19  6:54           ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
@ 2016-12-19  6:54           ` Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
                             ` (2 subsequent siblings)
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:54 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

We've decided to standardize on two flags for RISC-V: "-march" sets the
target architecture (which determines which instructions can be
generated), and "-mabi" sets the target ABI.  We needed to rework this
because the old flag set didn't support soft-float or single-float ABIs,
and didn't support an x32-style ABI on RISC-V.

Additionally, we've changed the behavior of the -march flag: it's now a
lot stricter and only parses things we can actually understand.
Additionally, it's now lowercase-only: the rationale is that while the
RISC-V ISA manual specifies that ISA strings are case-insensitive, in
Linux-land things are usually case-sensitive.  Since this flag can be
used to determine library paths, we didn't want to bake some
case-insensitivity in there that would case trouble later.

This patch implements these two new flags and removes the old flags that
could conflict with these.  There wasn't a RISC-V release before, so we
want to just support a clean flag set.

bfd/ChangeLog

2016-12-14 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.

binutils/ChangeLog

2016-12-14 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.

gas/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * config/tc-riscv.c (xlen): No longer used externally.
        * config/tc-riscv.h (xlen): Likewise.
        * config/tc-riscv.c (abi_xlen): New variable, holds the length of X-registers as used by the ABI.
        (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.

opcodes/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * riscv-dis.c (riscv_disassemble_insn): Default to the ELF's
        XLEN when none is provided.
---
 bfd/elfnn-riscv.c     |   4 +-
 binutils/readelf.c    |  21 +++++-
 gas/config/tc-riscv.c | 197 ++++++++++++++++++++++++--------------------------
 gas/config/tc-riscv.h |   1 -
 gas/doc/as.texinfo    |   5 +-
 gas/doc/c-riscv.texi  |  23 ++----
 include/elf/riscv.h   |  16 +++-
 opcodes/riscv-dis.c   |   8 +-
 8 files changed, 144 insertions(+), 131 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 461bce3..d76163e 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/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/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/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/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;
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 6/9] Don't define our own .p2align
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
                             ` (2 preceding siblings ...)
  2016-12-19  6:54           ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
@ 2016-12-19  6:54           ` Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
                             ` (4 subsequent siblings)
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:54 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

gas/ChangeLog

2015-12-14 Andrew Waterman <andrew@sifive.com>

        * config/tc-riscv.c (riscv_pseudo_table): Removed "align",
        "p2align", and "balign".
        * config/tc-riscv.c (s_align): Removed.
        * config/tc-riscv.h (riscv_handle_align): New function.
        (riscv_frag_align_code): Likewise.
        (riscv_make_nops): Likewise.
        * config/tc-riscv.c (riscv_handle_align): Likewise.
        (riscv_frag_align_code): Likewise.
        (riscv_make_nops): Likewise.
        * config/tc-riscv.h (MAX_MEM_FOR_RS_ALIGN_CODE): Changed to 7.
        (HANDLE_ALIGN): New define.
        (md_do_align): New define.
---
 gas/config/tc-riscv.c | 96 ++++++++++++++++++++++++++++++---------------------
 gas/config/tc-riscv.h | 14 ++++++--
 2 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 77c92cf..2d953c5 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2185,63 +2185,82 @@ s_bss (int ignore ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
-/* Align to a given power of two.  */
-
 static void
-s_align (int bytes_p)
+riscv_make_nops (char *buf, bfd_vma bytes)
 {
-  int fill_value = 0, fill_value_specified = 0;
-  int min_text_alignment = riscv_opts.rvc ? 2 : 4;
-  int alignment = get_absolute_expression(), bytes;
+  bfd_vma i = 0;
 
-  if (bytes_p)
+  if (bytes % 4 == 2)
     {
-      bytes = alignment;
-      if (bytes < 1 || (bytes & (bytes-1)) != 0)
-	as_bad (_("alignment not a power of 2: %d"), bytes);
-      for (alignment = 0; bytes > 1; bytes >>= 1)
-	alignment++;
+      md_number_to_chars (buf, RVC_NOP, 2);
+      i += 2;
     }
 
-  bytes = 1 << alignment;
+  gas_assert ((bytes - i) % 4 == 0);
 
-  if (alignment < 0 || alignment > 31)
-    as_bad (_("unsatisfiable alignment: %d"), alignment);
+  for ( ; i < bytes; i += 4)
+    md_number_to_chars (buf + i, RISCV_NOP, 4);
+}
 
-  if (*input_line_pointer == ',')
-    {
-      ++input_line_pointer;
-      fill_value = get_absolute_expression ();
-      fill_value_specified = 1;
-    }
+/* Called from md_do_align.  Used to create an alignment frag in a
+   code section by emitting a worst-case NOP sequence that the linker
+   will later relax to the correct number of NOPs.  We can't compute
+   the correct alignment now because of other linker relaxations.  */
+
+bfd_boolean
+riscv_frag_align_code (int n)
+{
+  bfd_vma bytes = (bfd_vma)1 << n;
+  bfd_vma min_text_alignment = riscv_opts.rvc ? 2 : 4;
+
+  /* When not relaxing, riscv_handle_align handles code alignment.  */
+  if (!riscv_opts.relax)
+    return FALSE;
 
-  if (!fill_value_specified
-      && subseg_text_p (now_seg)
-      && bytes > min_text_alignment)
+  if (bytes > min_text_alignment)
     {
-      /* Emit the worst-case NOP string.  The linker will delete any
-	 unnecessary NOPs.  This allows us to support code alignment
-	 in spite of linker relaxations.  */
-      bfd_vma i, worst_case_bytes = bytes - min_text_alignment;
+      bfd_vma worst_case_bytes = bytes - min_text_alignment;
       char *nops = frag_more (worst_case_bytes);
-      for (i = 0; i < worst_case_bytes - 2; i += 4)
-	md_number_to_chars (nops + i, RISCV_NOP, 4);
-      if (i < worst_case_bytes)
-	md_number_to_chars (nops + i, RVC_NOP, 2);
-
       expressionS ex;
+
       ex.X_op = O_constant;
       ex.X_add_number = worst_case_bytes;
 
+      riscv_make_nops (nops, worst_case_bytes);
+
       fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
 		   &ex, FALSE, BFD_RELOC_RISCV_ALIGN);
     }
-  else if (alignment)
-    frag_align (alignment, fill_value, 0);
 
-  record_alignment (now_seg, alignment);
+  return TRUE;
+}
 
-  demand_empty_rest_of_line ();
+/* Implement HANDLE_ALIGN.  */
+
+void
+riscv_handle_align (fragS *fragP)
+{
+  switch (fragP->fr_type)
+    {
+    case rs_align_code:
+      /* When relaxing, riscv_frag_align_code handles code alignment.  */
+      if (!riscv_opts.relax)
+	{
+	  bfd_signed_vma count = fragP->fr_next->fr_address
+				 - fragP->fr_address - fragP->fr_fix;
+
+	  if (count <= 0)
+	    break;
+
+	  count &= MAX_MEM_FOR_RS_ALIGN_CODE;
+	  riscv_make_nops (fragP->fr_literal + fragP->fr_fix, count);
+	  fragP->fr_var = count;
+	}
+      break;
+
+    default:
+      break;
+    }
 }
 
 int
@@ -2488,9 +2507,6 @@ static const pseudo_typeS riscv_pseudo_table[] =
   {"dtprelword", s_dtprel, 4},
   {"dtpreldword", s_dtprel, 8},
   {"bss", s_bss, 0},
-  {"align", s_align, 0},
-  {"p2align", s_align, 0},
-  {"balign", s_align, 1},
   {"uleb128", s_riscv_leb128, 0},
   {"sleb128", s_riscv_leb128, 1},
 
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 5e07fda..5d6b83f 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -48,8 +48,18 @@ extern int riscv_relax_frag (asection *, struct frag *, long);
 #define md_undefined_symbol(name)	(0)
 #define md_operand(x)
 
-/* FIXME: it is unclear if this is used, or if it is even correct.  */
-#define MAX_MEM_FOR_RS_ALIGN_CODE  (1 + 2)
+extern bfd_boolean riscv_frag_align_code (int);
+#define md_do_align(N, FILL, LEN, MAX, LABEL)				\
+  if ((N) != 0 && !(FILL) && !need_pass_2 && subseg_text_p (now_seg))	\
+    {									\
+      if (riscv_frag_align_code (N))					\
+	goto LABEL;							\
+    }
+
+extern void riscv_handle_align (fragS *);
+#define HANDLE_ALIGN riscv_handle_align
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE 7
 
 /* The ISA of the target may change based on command-line arguments.  */
 #define TARGET_FORMAT riscv_target_format()
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* RISC-V Fixes for 2.28 v4
  2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
                           ` (8 preceding siblings ...)
  2016-12-19  4:27         ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
@ 2016-12-19  6:54         ` Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
                             ` (8 more replies)
  9 siblings, 9 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:54 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

This patch set contains fixed ChangeLog entries.  The big one is combining
multiple repeat instances of the same filename into a single entry, I also
fixed a typo and merged some stray extra entries.

Thanks for all the help!

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 1/9] Improve a LD error message when linking elf32 and elf64
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
                             ` (6 preceding siblings ...)
  2016-12-19  6:54           ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
@ 2016-12-19  6:54           ` Palmer Dabbelt
  2016-12-19  8:46           ` RISC-V Fixes for 2.28 v4 Alan Modra
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:54 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman, Palmer Dabbelt

I recently ran into this error message and found it's not helpful: it
just tells me some temporary file can't be linked.  This slightly
improved one at least tells me it's because of an elf32/elf64 conflict.

bfd/ChangeLog

        * elfnn-riscv.c (_bfd_riscv_elf_merge_private_bfd_data): Improve
        error message when linking elf32 and elf64.
---
 bfd/elfnn-riscv.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 4f11cf6..88d5d66 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2561,8 +2561,9 @@ _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
     {
       (*_bfd_error_handler)
-	(_("%B: ABI is incompatible with that of the selected emulation"),
-	 ibfd);
+	(_("%B: ABI is incompatible with that of the selected emulation:\n"
+           "  target emulation `%s' does not match `%s'"),
+	 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
       return FALSE;
     }
 
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 7/9] Add canonical JALR assembly representation
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
                             ` (3 preceding siblings ...)
  2016-12-19  6:54           ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
@ 2016-12-19  6:54           ` Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
                             ` (3 subsequent siblings)
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:54 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

    jalr rd,offset(rs1)

rather than

    jalr rd,rs1,offset

This matches the format of other instructions.

opcodes/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * riscv-opc.c (riscv_opcodes): Change jr and jalr to "o(s)"
        format.
---
 opcodes/riscv-opc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 256e089..69fca09 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -132,11 +132,14 @@ const struct riscv_opcode riscv_opcodes[] =
 {"ret",       "I",   "",  MATCH_JALR | (X_RA << OP_SH_RS1), MASK_JALR | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
 {"jr",        "C",   "d",  MATCH_C_JR, MASK_C_JR, match_rd_nonzero, INSN_ALIAS },
 {"jr",        "I",   "s",  MATCH_JALR, MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jr",        "I",   "o(s)",  MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jr",        "I",   "s,j",  MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "C",   "d",  MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, INSN_ALIAS },
 {"jalr",      "I",   "s",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jalr",      "I",   "o(s)",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "I",   "s,j",  MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS },
 {"jalr",      "I",   "d,s",  MATCH_JALR, MASK_JALR | MASK_IMM, match_opcode, INSN_ALIAS },
+{"jalr",      "I",   "d,o(s)",  MATCH_JALR, MASK_JALR, match_opcode, 0 },
 {"jalr",      "I",   "d,s,j",  MATCH_JALR, MASK_JALR, match_opcode, 0 },
 {"j",         "C",   "Ca",  MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS },
 {"j",         "I",   "a",  MATCH_JAL, MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS },
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 3/9] Rework RISC-V relocations
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
@ 2016-12-19  6:54           ` Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
                             ` (5 subsequent siblings)
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:54 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

Before this commit we didn't cleanly support CFI directives because the
internal offsets used to get relaxed which broke them.  This patch
significantly reworks how we handle linker relaxations:

 * DWARF is now properly supported

 * There is a ".option norelax" to disable relaxations, for when users
   write assembly that can't be relaxed (if it's to be later patched up,
   for example).

 * There is an additional _RELAX relocation that specifies when previous
   relocations can be relaxed.

We're in the process of documenting the RISC-V ELF ABI, which will
include documentation of our relocations

  https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md

but we expect that this relocation set will remain ABI compatible in the
future (ie, it's safe to release).

Thanks to Kuan-Lin Chen for figuring out how to correctly relax the
debug info!

bfd/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>
           Kuan-Lin Chen <kuanlinchentw@gmail.com>

        * reloc.c (BFD_RELOC_RISCV_TPREL_I): New relocation.
        (BFD_RELOC_RISCV_TPREL_S): Likewise.
        (BFD_RELOC_RISCV_RELAX): Likewise.
        (BFD_RELOC_RISCV_CFA): Likewise.
        (BFD_RELOC_RISCV_SUB6): Likewise.
        (BFD_RELOC_RISCV_SET8): Likewise.
        (BFD_RELOC_RISCV_SET8): Likewise.
        (BFD_RELOC_RISCV_SET16): Likewise.
        (BFD_RELOC_RISCV_SET32): Likewise.
        * bfd-in2.h: Regenerate.
        * libbfd.h: Likewise.
        * elfnn-riscv.c (perform_relocation): Handle the new
        relocations.
        (_bfd_riscv_relax_tls_le): Likewise.
        (_bfd_riscv_relax_align): Likewise.
        (_bfd_riscv_relax_section): Likewise.
        (howto_table): Likewise.
        (riscv_reloc_map): Likewise.
        * elfnn-riscv.c (relax_func_t): New type.
        (_bfd_riscv_relax_call): Add reserve_size argument, which
        controls the maximal offset pessimism.
        (_bfd_riscv_relax_lui): Likewise.
        (_bfd_riscv_relax_tls_le): Likewise.
        (_bfd_riscv_relax_align): Likewise.
        (_bfd_riscv_relax_section): Compute the required reserve size
        when relocating and use it to when calling relax_func.

gas/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>
           Kuan-Lin Chen <kuanlinchentw@gmail.com>

        * config/tc-riscv.c (riscv_set_options): Add relax.
        (riscv_opts): Likewise.
        (s_riscv_option): Add relax and norelax.
        (riscv_apply_const_reloc): New function.
        (append_insn): Move constant relocation handling to
        riscv_apply_const_reloc.
        (md_pcrel_from): Likewise.
        (parse_relocation): Skip BFD_RELOC_UNUSED.
        (md_pcrel_from): Handle BFD_RELOC_RISCV_SUB6,
        BFD_RELOC_RISCV_RELAX, BFD_RELOC_RISCV_CFA.
        * config/tc-riscv.c (md_apply_fix): Likewise.
        (riscv_pre_output_hook): New function.
        * config/tc-riscv.h (md_pre_output_hook): Use
        riscv_pre_output_hook.
        (DWARF_CIE_DATA_ALIGNMENT): Always -4.
---
 bfd/bfd-in2.h         |   9 +++
 bfd/elfnn-riscv.c     |  93 ++++++++++++++++++----
 bfd/elfxx-riscv.c     | 128 ++++++++++++++++++++++++++++++
 bfd/libbfd.h          |   9 +++
 bfd/reloc.c           |  18 +++++
 gas/config/tc-riscv.c | 213 +++++++++++++++++++++++++++++++++++++-------------
 gas/config/tc-riscv.h |   7 +-
 include/elf/riscv.h   |   8 ++
 8 files changed, 416 insertions(+), 69 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 1c6b70f..b5ac178 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -4737,6 +4737,15 @@ number for the SBIC, SBIS, SBI and CBI instructions  */
   BFD_RELOC_RISCV_RVC_LUI,
   BFD_RELOC_RISCV_GPREL_I,
   BFD_RELOC_RISCV_GPREL_S,
+  BFD_RELOC_RISCV_TPREL_I,
+  BFD_RELOC_RISCV_TPREL_S,
+  BFD_RELOC_RISCV_RELAX,
+  BFD_RELOC_RISCV_CFA,
+  BFD_RELOC_RISCV_SUB6,
+  BFD_RELOC_RISCV_SET6,
+  BFD_RELOC_RISCV_SET8,
+  BFD_RELOC_RISCV_SET16,
+  BFD_RELOC_RISCV_SET32,
 
 /* Renesas RL78 Relocations.  */
   BFD_RELOC_RL78_NEG8,
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index e18bd71..5976118 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1493,6 +1493,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_LO12_I:
     case R_RISCV_GPREL_I:
     case R_RISCV_TPREL_LO12_I:
+    case R_RISCV_TPREL_I:
     case R_RISCV_PCREL_LO12_I:
       value = ENCODE_ITYPE_IMM (value);
       break;
@@ -1500,6 +1501,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_LO12_S:
     case R_RISCV_GPREL_S:
     case R_RISCV_TPREL_LO12_S:
+    case R_RISCV_TPREL_S:
     case R_RISCV_PCREL_LO12_S:
       value = ENCODE_STYPE_IMM (value);
       break;
@@ -1548,10 +1550,15 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_ADD16:
     case R_RISCV_ADD32:
     case R_RISCV_ADD64:
+    case R_RISCV_SUB6:
     case R_RISCV_SUB8:
     case R_RISCV_SUB16:
     case R_RISCV_SUB32:
     case R_RISCV_SUB64:
+    case R_RISCV_SET6:
+    case R_RISCV_SET8:
+    case R_RISCV_SET16:
+    case R_RISCV_SET32:
     case R_RISCV_TLS_DTPREL32:
     case R_RISCV_TLS_DTPREL64:
       break;
@@ -1817,6 +1824,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
       switch (r_type)
 	{
 	case R_RISCV_NONE:
+	case R_RISCV_RELAX:
 	case R_RISCV_TPREL_ADD:
 	case R_RISCV_COPY:
 	case R_RISCV_JUMP_SLOT:
@@ -1830,6 +1838,10 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_RVC_LUI:
 	case R_RISCV_LO12_I:
 	case R_RISCV_LO12_S:
+	case R_RISCV_SET6:
+	case R_RISCV_SET8:
+	case R_RISCV_SET16:
+	case R_RISCV_SET32:
 	  /* These require no special handling beyond perform_relocation.  */
 	  break;
 
@@ -1923,6 +1935,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	  }
 	  break;
 
+	case R_RISCV_SUB6:
 	case R_RISCV_SUB8:
 	case R_RISCV_SUB16:
 	case R_RISCV_SUB32:
@@ -1953,6 +1966,11 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	case R_RISCV_TPREL_LO12_I:
 	case R_RISCV_TPREL_LO12_S:
 	  relocation = tpoff (info, relocation);
+	  break;
+
+	case R_RISCV_TPREL_I:
+	case R_RISCV_TPREL_S:
+	  relocation = tpoff (info, relocation);
 	  if (VALID_ITYPE_IMM (relocation + rel->r_addend))
 	    {
 	      /* We can use tp as the base register.  */
@@ -1961,6 +1979,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
 	      insn |= X_TP << OP_SH_RS1;
 	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
 	    }
+	  else
+	    r = bfd_reloc_overflow;
 	  break;
 
 	case R_RISCV_GPREL_I:
@@ -2668,6 +2688,11 @@ riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count)
   return TRUE;
 }
 
+typedef bfd_boolean (*relax_func_t) (bfd *, asection *, asection *,
+				     struct bfd_link_info *,
+				     Elf_Internal_Rela *,
+				     bfd_vma, bfd_vma, bfd_vma, bfd_boolean *);
+
 /* Relax AUIPC + JALR into JAL.  */
 
 static bfd_boolean
@@ -2675,7 +2700,8 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 		       struct bfd_link_info *link_info,
 		       Elf_Internal_Rela *rel,
 		       bfd_vma symval,
-		       unsigned int max_alignment,
+		       bfd_vma max_alignment,
+		       bfd_vma reserve_size ATTRIBUTE_UNUSED,
 		       bfd_boolean *again)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2758,6 +2784,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
 		      unsigned int max_alignment,
+		      bfd_vma reserve_size,
 		      bfd_boolean *again)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2773,8 +2800,10 @@ _bfd_riscv_relax_lui (bfd *abfd,
   /* Is the reference in range of x0 or gp?
      Valid gp range conservatively because of alignment issue.  */
   if (VALID_ITYPE_IMM (symval)
-      || (symval >= gp && VALID_ITYPE_IMM (symval - gp + max_alignment))
-      || (symval < gp && VALID_ITYPE_IMM (symval - gp - max_alignment)))
+      || (symval >= gp
+	  && VALID_ITYPE_IMM (symval - gp + max_alignment + reserve_size))
+      || (symval < gp
+	  && VALID_ITYPE_IMM (symval - gp - max_alignment - reserve_size)))
     {
       unsigned sym = ELFNN_R_SYM (rel->r_info);
       switch (ELFNN_R_TYPE (rel->r_info))
@@ -2832,20 +2861,35 @@ _bfd_riscv_relax_tls_le (bfd *abfd,
 			 struct bfd_link_info *link_info,
 			 Elf_Internal_Rela *rel,
 			 bfd_vma symval,
-			 unsigned int max_alignment ATTRIBUTE_UNUSED,
+			 bfd_vma max_alignment ATTRIBUTE_UNUSED,
+			 bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			 bfd_boolean *again)
 {
   /* See if this symbol is in range of tp.  */
   if (RISCV_CONST_HIGH_PART (tpoff (link_info, symval)) != 0)
     return TRUE;
 
-  /* We can delete the unnecessary LUI and tp add.  The LO12 reloc will be
-     made directly tp-relative.  */
   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
-  rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
+  switch (ELFNN_R_TYPE (rel->r_info))
+    {
+    case R_RISCV_TPREL_LO12_I:
+      rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_I);
+      return TRUE;
 
-  *again = TRUE;
-  return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
+    case R_RISCV_TPREL_LO12_S:
+      rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_S);
+      return TRUE;
+
+    case R_RISCV_TPREL_HI20:
+    case R_RISCV_TPREL_ADD:
+      /* We can delete the unnecessary instruction and reloc.  */
+      rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
+      *again = TRUE;
+      return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
+
+    default:
+      abort ();
+    }
 }
 
 /* Implement R_RISCV_ALIGN by deleting excess alignment NOPs.  */
@@ -2857,6 +2901,7 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
 			unsigned int max_alignment ATTRIBUTE_UNUSED,
+			bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			bfd_boolean *again ATTRIBUTE_UNUSED)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
@@ -2909,7 +2954,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
   Elf_Internal_Rela *relocs;
   bfd_boolean ret = FALSE;
   unsigned int i;
-  unsigned int max_alignment;
+  bfd_vma max_alignment, reserve_size = 0;
 
   *again = FALSE;
 
@@ -2935,7 +2980,7 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
     {
       asection *sym_sec;
       Elf_Internal_Rela *rel = relocs + i;
-      typeof (&_bfd_riscv_relax_call) relax_func = NULL;
+      relax_func_t relax_func;
       int type = ELFNN_R_TYPE (rel->r_info);
       bfd_vma symval;
 
@@ -2947,13 +2992,26 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 		   || type == R_RISCV_LO12_I
 		   || type == R_RISCV_LO12_S)
 	    relax_func = _bfd_riscv_relax_lui;
-	  else if (type == R_RISCV_TPREL_HI20 || type == R_RISCV_TPREL_ADD)
+	  else if (type == R_RISCV_TPREL_HI20
+		   || type == R_RISCV_TPREL_ADD
+		   || type == R_RISCV_TPREL_LO12_I
+		   || type == R_RISCV_TPREL_LO12_S)
 	    relax_func = _bfd_riscv_relax_tls_le;
+	  else
+	    continue;
+
+	  /* Only relax this reloc if it is paired with R_RISCV_RELAX.  */
+	  if (i == sec->reloc_count - 1
+	      || ELFNN_R_TYPE ((rel + 1)->r_info) != R_RISCV_RELAX
+	      || rel->r_offset != (rel + 1)->r_offset)
+	    continue;
+
+	  /* Skip over the R_RISCV_RELAX.  */
+	  i++;
 	}
       else if (type == R_RISCV_ALIGN)
 	relax_func = _bfd_riscv_relax_align;
-
-      if (!relax_func)
+      else
 	continue;
 
       data->relocs = relocs;
@@ -2978,6 +3036,8 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	  /* A local symbol.  */
 	  Elf_Internal_Sym *isym = ((Elf_Internal_Sym *) symtab_hdr->contents
 				    + ELFNN_R_SYM (rel->r_info));
+	  reserve_size = (isym->st_size - rel->r_addend) > isym->st_size
+	    ? 0 : isym->st_size - rel->r_addend;
 
 	  if (isym->st_shndx == SHN_UNDEF)
 	    sym_sec = sec, symval = sec_addr (sec) + rel->r_offset;
@@ -3011,13 +3071,16 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec,
 	  else
 	    symval = sec_addr (h->root.u.def.section) + h->root.u.def.value;
 
+	  if (h->type != STT_FUNC)
+	    reserve_size =
+	      (h->size - rel->r_addend) > h->size ? 0 : h->size - rel->r_addend;
 	  sym_sec = h->root.u.def.section;
 	}
 
       symval += rel->r_addend;
 
       if (!relax_func (abfd, sec, sym_sec, info, rel, symval,
-		       max_alignment, again))
+		       max_alignment, reserve_size, again))
 	goto fail;
     }
 
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 0fb250d..3d935cf 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -713,6 +713,126 @@ static reloc_howto_type howto_table[] =
 	 0,				/* src_mask */
 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
 	 FALSE),			/* pcrel_offset */
+
+  /* TP-relative TLS LE load.  */
+  HOWTO (R_RISCV_TPREL_I,		/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TPREL_I",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* TP-relative TLS LE store.  */
+  HOWTO (R_RISCV_TPREL_S,		/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_signed,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_TPREL_S",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* The paired relocation may be relaxed.  */
+  HOWTO (R_RISCV_RELAX,			/* type */
+	 0,				/* rightshift */
+	 3,				/* size */
+	 0,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_RELAX",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 6-bit in-place addition, for local label subtraction.  */
+  HOWTO (R_RISCV_SUB6,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SUB6",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0x3f,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 6-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET6,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET6",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 0x3f,				/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 8-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET8,			/* type */
+	 0,				/* rightshift */
+	 0,				/* size */
+	 8,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET8",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 16-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET16,			/* type */
+	 0,				/* rightshift */
+	 1,				/* size */
+	 16,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET16",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
+
+  /* 32-bit in-place setting, for local label subtraction.  */
+  HOWTO (R_RISCV_SET32,			/* type */
+	 0,				/* rightshift */
+	 2,				/* size */
+	 32,				/* bitsize */
+	 FALSE,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,		/* special_function */
+	 "R_RISCV_SET32",		/* name */
+	 FALSE,				/* partial_inplace */
+	 0,				/* src_mask */
+	 MINUS_ONE,			/* dst_mask */
+	 FALSE),			/* pcrel_offset */
 };
 
 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
@@ -766,6 +886,14 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
   { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
   { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
+  { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
+  { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
+  { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
+  { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
+  { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
+  { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
+  { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
+  { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
 };
 
 /* Given a BFD reloc type, return a howto structure.  */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 5ec3993..76bbd09 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2204,6 +2204,15 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_RISCV_RVC_LUI",
   "BFD_RELOC_RISCV_GPREL_I",
   "BFD_RELOC_RISCV_GPREL_S",
+  "BFD_RELOC_RISCV_TPREL_I",
+  "BFD_RELOC_RISCV_TPREL_S",
+  "BFD_RELOC_RISCV_RELAX",
+  "BFD_RELOC_RISCV_CFA",
+  "BFD_RELOC_RISCV_SUB6",
+  "BFD_RELOC_RISCV_SET6",
+  "BFD_RELOC_RISCV_SET8",
+  "BFD_RELOC_RISCV_SET16",
+  "BFD_RELOC_RISCV_SET32",
   "BFD_RELOC_RL78_NEG8",
   "BFD_RELOC_RL78_NEG16",
   "BFD_RELOC_RL78_NEG24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 56cd79b..3c7b606 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -5124,6 +5124,24 @@ ENUMX
   BFD_RELOC_RISCV_GPREL_I
 ENUMX
   BFD_RELOC_RISCV_GPREL_S
+ENUMX
+  BFD_RELOC_RISCV_TPREL_I
+ENUMX
+  BFD_RELOC_RISCV_TPREL_S
+ENUMX
+  BFD_RELOC_RISCV_RELAX
+ENUMX
+  BFD_RELOC_RISCV_CFA
+ENUMX
+  BFD_RELOC_RISCV_SUB6
+ENUMX
+  BFD_RELOC_RISCV_SET6
+ENUMX
+  BFD_RELOC_RISCV_SET8
+ENUMX
+  BFD_RELOC_RISCV_SET16
+ENUMX
+  BFD_RELOC_RISCV_SET32
 ENUMDOC
   RISC-V relocations.
 
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index d8a627d..d011864 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -74,12 +74,14 @@ struct riscv_set_options
 {
   int pic; /* Generate position-independent code.  */
   int rvc; /* Generate RVC code.  */
+  int relax; /* Emit relocs the linker is allowed to relax.  */
 };
 
 static struct riscv_set_options riscv_opts =
 {
   0,	/* pic */
   0,	/* rvc */
+  1,	/* relax */
 };
 
 static void
@@ -648,6 +650,28 @@ md_begin (void)
   record_alignment (text_section, riscv_opts.rvc ? 1 : 2);
 }
 
+static insn_t
+riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type, bfd_vma value)
+{
+  switch (reloc_type)
+    {
+    case BFD_RELOC_32:
+      return value;
+
+    case BFD_RELOC_RISCV_HI20:
+      return ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
+
+    case BFD_RELOC_RISCV_LO12_S:
+      return ENCODE_STYPE_IMM (value);
+
+    case BFD_RELOC_RISCV_LO12_I:
+      return ENCODE_ITYPE_IMM (value);
+
+    default:
+      abort ();
+    }
+}
+
 /* Output an instruction.  IP is the instruction information.
    ADDRESS_EXPR is an operand of the instruction to be used with
    RELOC_TYPE.  */
@@ -676,43 +700,22 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
 	  return;
 	}
       else if (address_expr->X_op == O_constant)
+	ip->insn_opcode |= riscv_apply_const_reloc (reloc_type,
+						    address_expr->X_add_number);
+      else
 	{
-	  switch (reloc_type)
-	    {
-	    case BFD_RELOC_32:
-	      ip->insn_opcode |= address_expr->X_add_number;
-	      goto append;
+	  howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
+	  if (howto == NULL)
+	    as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
 
-	    case BFD_RELOC_RISCV_HI20:
-	      {
-		insn_t imm = RISCV_CONST_HIGH_PART (address_expr->X_add_number);
-		ip->insn_opcode |= ENCODE_UTYPE_IMM (imm);
-		goto append;
-	      }
-
-	    case BFD_RELOC_RISCV_LO12_S:
-	      ip->insn_opcode |= ENCODE_STYPE_IMM (address_expr->X_add_number);
-	      goto append;
+	  ip->fixp = fix_new_exp (ip->frag, ip->where,
+				  bfd_get_reloc_size (howto),
+				  address_expr, FALSE, reloc_type);
 
-	    case BFD_RELOC_RISCV_LO12_I:
-	      ip->insn_opcode |= ENCODE_ITYPE_IMM (address_expr->X_add_number);
-	      goto append;
-
-	    default:
-	      break;
-	    }
+	  ip->fixp->fx_tcbit = riscv_opts.relax;
 	}
-
-	howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
-	if (howto == NULL)
-	  as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
-
-	ip->fixp = fix_new_exp (ip->frag, ip->where,
-				bfd_get_reloc_size (howto),
-				address_expr, FALSE, reloc_type);
     }
 
-append:
   add_fixed_insn (ip);
   install_insn (ip);
 }
@@ -1085,7 +1088,8 @@ parse_relocation (char **str, bfd_reloc_code_real_type *reloc,
 
 	/* Check whether the output BFD supports this relocation.
 	   If not, issue an error and fall back on something safe.  */
-	if (!bfd_reloc_type_lookup (stdoutput, percent_op->reloc))
+	if (*reloc != BFD_RELOC_UNUSED
+	    && !bfd_reloc_type_lookup (stdoutput, *reloc))
 	  {
 	    as_bad ("relocation %s isn't supported by the current ABI",
 		    percent_op->str);
@@ -1826,45 +1830,56 @@ md_pcrel_from (fixS *fixP)
 void
 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 {
+  unsigned int subtype;
   bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
+  bfd_boolean relaxable = FALSE;
 
   /* Remember value for tc_gen_reloc.  */
   fixP->fx_addnumber = *valP;
 
   switch (fixP->fx_r_type)
     {
-    case BFD_RELOC_RISCV_TLS_GOT_HI20:
-    case BFD_RELOC_RISCV_TLS_GD_HI20:
-    case BFD_RELOC_RISCV_TLS_DTPREL32:
-    case BFD_RELOC_RISCV_TLS_DTPREL64:
-    case BFD_RELOC_RISCV_TPREL_HI20:
-    case BFD_RELOC_RISCV_TPREL_LO12_I:
-    case BFD_RELOC_RISCV_TPREL_LO12_S:
-    case BFD_RELOC_RISCV_TPREL_ADD:
-      S_SET_THREAD_LOCAL (fixP->fx_addsy);
-      /* Fall through.  */
-
-    case BFD_RELOC_RISCV_GOT_HI20:
-    case BFD_RELOC_RISCV_PCREL_HI20:
     case BFD_RELOC_RISCV_HI20:
     case BFD_RELOC_RISCV_LO12_I:
     case BFD_RELOC_RISCV_LO12_S:
+      bfd_putl32 (riscv_apply_const_reloc (fixP->fx_r_type, *valP)
+		  | bfd_getl32 (buf), buf);
+      relaxable = TRUE;
+      break;
+
+    case BFD_RELOC_RISCV_GOT_HI20:
+    case BFD_RELOC_RISCV_PCREL_HI20:
     case BFD_RELOC_RISCV_ADD8:
     case BFD_RELOC_RISCV_ADD16:
     case BFD_RELOC_RISCV_ADD32:
     case BFD_RELOC_RISCV_ADD64:
+    case BFD_RELOC_RISCV_SUB6:
     case BFD_RELOC_RISCV_SUB8:
     case BFD_RELOC_RISCV_SUB16:
     case BFD_RELOC_RISCV_SUB32:
     case BFD_RELOC_RISCV_SUB64:
-      gas_assert (fixP->fx_addsy != NULL);
-      /* Nothing needed to do.  The value comes from the reloc entry.  */
+    case BFD_RELOC_RISCV_RELAX:
+      break;
+
+    case BFD_RELOC_RISCV_TPREL_HI20:
+    case BFD_RELOC_RISCV_TPREL_LO12_I:
+    case BFD_RELOC_RISCV_TPREL_LO12_S:
+    case BFD_RELOC_RISCV_TPREL_ADD:
+      relaxable = TRUE;
+      /* Fall through.  */
+
+    case BFD_RELOC_RISCV_TLS_GOT_HI20:
+    case BFD_RELOC_RISCV_TLS_GD_HI20:
+    case BFD_RELOC_RISCV_TLS_DTPREL32:
+    case BFD_RELOC_RISCV_TLS_DTPREL64:
+      S_SET_THREAD_LOCAL (fixP->fx_addsy);
       break;
 
     case BFD_RELOC_64:
     case BFD_RELOC_32:
     case BFD_RELOC_16:
     case BFD_RELOC_8:
+    case BFD_RELOC_RISCV_CFA:
       if (fixP->fx_addsy && fixP->fx_subsy)
 	{
 	  fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
@@ -1895,6 +1910,49 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
 	      break;
 
+	    case BFD_RELOC_RISCV_CFA:
+	      /* Load the byte to get the subtype.  */
+	      subtype = bfd_get_8 (NULL, &fixP->fx_frag->fr_literal[fixP->fx_where]);
+	      switch (subtype)
+		{
+		case DW_CFA_advance_loc1:
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET8;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
+		  break;
+
+		case DW_CFA_advance_loc2:
+		  fixP->fx_size = 2;
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_size = 2;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET16;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
+		  break;
+
+		case DW_CFA_advance_loc4:
+		  fixP->fx_size = 4;
+		  fixP->fx_where++;
+		  fixP->fx_next->fx_size = 4;
+		  fixP->fx_next->fx_where++;
+		  fixP->fx_r_type = BFD_RELOC_RISCV_SET32;
+		  fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
+		  break;
+
+		default:
+		  if (subtype < 0x80 && (subtype & 0x40))
+		    {
+		      /* DW_CFA_advance_loc */
+		      fixP->fx_r_type = BFD_RELOC_RISCV_SET6;
+		      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB6;
+		    }
+		  else
+		    as_fatal (_("internal error: bad CFA value #%d"), subtype);
+		  break;
+		}
+	      break;
+
 	    default:
 	      /* This case is unreachable.  */
 	      abort ();
@@ -1954,10 +2012,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	}
       break;
 
-    case BFD_RELOC_RISCV_PCREL_LO12_S:
-    case BFD_RELOC_RISCV_PCREL_LO12_I:
     case BFD_RELOC_RISCV_CALL:
     case BFD_RELOC_RISCV_CALL_PLT:
+      relaxable = TRUE;
+      break;
+
+    case BFD_RELOC_RISCV_PCREL_LO12_S:
+    case BFD_RELOC_RISCV_PCREL_LO12_I:
     case BFD_RELOC_RISCV_ALIGN:
       break;
 
@@ -1966,8 +2027,54 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL)
 	as_fatal (_("internal error: bad relocation #%d"), fixP->fx_r_type);
     }
+
+  /* Add an R_RISCV_RELAX reloc if the reloc is relaxable.  */
+  if (relaxable && fixP->fx_tcbit && fixP->fx_addsy != NULL)
+    {
+      fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
+      fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL;
+      fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELAX;
+    }
 }
 
+/* Because the value of .cfi_remember_state may changed after relaxation,
+   we insert a fix to relocate it again in link-time.  */
+
+void
+riscv_pre_output_hook (void)
+{
+  const frchainS *frch;
+  const asection *s;
+
+  for (s = stdoutput->sections; s; s = s->next)
+    for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next)
+      {
+	const fragS *frag;
+
+	for (frag = frch->frch_root; frag; frag = frag->fr_next)
+	  {
+	    if (frag->fr_type == rs_cfa)
+	      {
+		const fragS *loc4_frag;
+		expressionS exp;
+
+		symbolS *add_symbol = frag->fr_symbol->sy_value.X_add_symbol;
+		symbolS *op_symbol = frag->fr_symbol->sy_value.X_op_symbol;
+
+		exp.X_op = O_subtract;
+		exp.X_add_symbol = add_symbol;
+		exp.X_add_number = 0;
+		exp.X_op_symbol = op_symbol;
+
+		loc4_frag = (fragS *) frag->fr_opcode;
+		fix_new_exp (loc4_frag, (int) frag->fr_offset, 1, &exp, 0,
+			     BFD_RELOC_RISCV_CFA);
+	      }
+	  }
+      }
+}
+
+
 /* This structure is used to hold a stack of .option values.  */
 
 struct riscv_option_stack
@@ -1998,10 +2105,10 @@ 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, "relax") == 0)
+    riscv_opts.relax = TRUE;
+  else if (strcmp (name, "norelax") == 0)
+    riscv_opts.relax = FALSE;
   else if (strcmp (name, "push") == 0)
     {
       struct riscv_option_stack *s;
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index c2a11ce..32cf3ee 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -61,6 +61,9 @@ extern void riscv_after_parse_args (void);
 #define md_parse_long_option(arg) riscv_parse_long_option (arg)
 extern int riscv_parse_long_option (const char *);
 
+#define md_pre_output_hook riscv_pre_output_hook()
+extern void riscv_pre_output_hook (void);
+
 /* Let the linker resolve all the relocs due to relaxation.  */
 #define tc_fix_adjustable(fixp) 0
 #define md_allow_local_subtract(l,r,s) 0
@@ -93,7 +96,9 @@ extern int tc_riscv_regname_to_dw2regnum (char *);
 
 extern unsigned xlen;
 #define DWARF2_DEFAULT_RETURN_COLUMN X_RA
-#define DWARF2_CIE_DATA_ALIGNMENT (-(int) (xlen / 8))
+
+/* Even on RV64, use 4-byte alignment, as F registers may be only 32 bits.  */
+#define DWARF2_CIE_DATA_ALIGNMENT -4
 
 #define elf_tc_final_processing riscv_elf_final_processing
 extern void riscv_elf_final_processing (void);
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 8415659..4407611 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -79,6 +79,14 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type)
   RELOC_NUMBER (R_RISCV_RVC_LUI, 46)
   RELOC_NUMBER (R_RISCV_GPREL_I, 47)
   RELOC_NUMBER (R_RISCV_GPREL_S, 48)
+  RELOC_NUMBER (R_RISCV_TPREL_I, 49)
+  RELOC_NUMBER (R_RISCV_TPREL_S, 50)
+  RELOC_NUMBER (R_RISCV_RELAX, 51)
+  RELOC_NUMBER (R_RISCV_SUB6, 52)
+  RELOC_NUMBER (R_RISCV_SET6, 53)
+  RELOC_NUMBER (R_RISCV_SET8, 54)
+  RELOC_NUMBER (R_RISCV_SET16, 55)
+  RELOC_NUMBER (R_RISCV_SET32, 56)
 END_RELOC_NUMBERS (R_RISCV_max)
 
 /* Processor specific flags for the ELF header e_flags field.  */
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [PATCH 4/9] Fix an integer overflow in relocation handling
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
                             ` (5 preceding siblings ...)
  2016-12-19  6:54           ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
@ 2016-12-19  6:54           ` Palmer Dabbelt
  2016-12-19  6:54           ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
  2016-12-19  8:46           ` RISC-V Fixes for 2.28 v4 Alan Modra
  8 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19  6:54 UTC (permalink / raw)
  To: amodra, binutils; +Cc: Andrew Waterman

From: Andrew Waterman <andrew@sifive.com>

bfd/ChangeLog

2016-12-14 Andrew Waterman <andrew@sifive.com>

        * elfnn-riscv.c (bfd_riscv_get_max_alignment): Return bfd_vma
        instead of unsigned int.
        (_bfd_riscv_relax_lui): Change the type of max_alignment to
        bfd_vma.
        (_bfd_riscv_relax_align): Likewise.
---
 bfd/elfnn-riscv.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 5976118..461bce3 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -2759,7 +2759,7 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
 
 /* Traverse all output sections and return the max alignment.  */
 
-static unsigned int
+static bfd_vma
 _bfd_riscv_get_max_alignment (asection *sec)
 {
   unsigned int max_alignment_power = 0;
@@ -2771,7 +2771,7 @@ _bfd_riscv_get_max_alignment (asection *sec)
 	max_alignment_power = o->alignment_power;
     }
 
-  return 1 << max_alignment_power;
+  return (bfd_vma) 1 << max_alignment_power;
 }
 
 /* Relax non-PIC global variable references.  */
@@ -2783,7 +2783,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
 		      struct bfd_link_info *link_info,
 		      Elf_Internal_Rela *rel,
 		      bfd_vma symval,
-		      unsigned int max_alignment,
+		      bfd_vma max_alignment,
 		      bfd_vma reserve_size,
 		      bfd_boolean *again)
 {
@@ -2900,7 +2900,7 @@ _bfd_riscv_relax_align (bfd *abfd, asection *sec,
 			struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
 			Elf_Internal_Rela *rel,
 			bfd_vma symval,
-			unsigned int max_alignment ATTRIBUTE_UNUSED,
+			bfd_vma max_alignment ATTRIBUTE_UNUSED,
 			bfd_vma reserve_size ATTRIBUTE_UNUSED,
 			bfd_boolean *again ATTRIBUTE_UNUSED)
 {
-- 
2.10.2

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: RISC-V Fixes for 2.28 v4
  2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
                             ` (7 preceding siblings ...)
  2016-12-19  6:54           ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
@ 2016-12-19  8:46           ` Alan Modra
  2016-12-19 18:01             ` Palmer Dabbelt
  8 siblings, 1 reply; 57+ messages in thread
From: Alan Modra @ 2016-12-19  8:46 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils, Andrew Waterman

On Sun, Dec 18, 2016 at 10:53:45PM -0800, Palmer Dabbelt wrote:
> This patch set contains fixed ChangeLog entries.  The big one is combining
> multiple repeat instances of the same filename into a single entry, I also
> fixed a typo and merged some stray extra entries.

Much better.  Can you commit this yourself, or would you rather
someone else did?

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: RISC-V Fixes for 2.28 v4
  2016-12-19  8:46           ` RISC-V Fixes for 2.28 v4 Alan Modra
@ 2016-12-19 18:01             ` Palmer Dabbelt
  2016-12-20  2:01               ` Alan Modra
  0 siblings, 1 reply; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-19 18:01 UTC (permalink / raw)
  To: amodra; +Cc: binutils, Andrew Waterman

On Mon, 19 Dec 2016 00:46:18 PST (-0800), amodra@gmail.com wrote:
> On Sun, Dec 18, 2016 at 10:53:45PM -0800, Palmer Dabbelt wrote:
>> This patch set contains fixed ChangeLog entries.  The big one is combining
>> multiple repeat instances of the same filename into a single entry, I also
>> fixed a typo and merged some stray extra entries.
>
> Much better.  Can you commit this yourself, or would you rather
> someone else did?

As far as I know, I don't have commit access.  I'm listed in a MAINTAINERS
file, but I haven't given anyone a SSH key (unless it's tied to my GNU account
somehow).

If it's not too much work, it'd be great if you could commit these -- even if I
have commit access, it'll probably take a bit to figure out how to do it
correctly :).

Thanks for all the feedback!

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: RISC-V Fixes for 2.28 v4
  2016-12-20  2:01               ` Alan Modra
@ 2016-12-20  2:01                 ` Palmer Dabbelt
  0 siblings, 0 replies; 57+ messages in thread
From: Palmer Dabbelt @ 2016-12-20  2:01 UTC (permalink / raw)
  To: amodra; +Cc: binutils, Andrew Waterman

On Mon, 19 Dec 2016 18:00:42 PST (-0800), amodra@gmail.com wrote:
> On Mon, Dec 19, 2016 at 10:01:10AM -0800, Palmer Dabbelt wrote:
>> If it's not too much work, it'd be great if you could commit these
>
> Committed with a few more tidies, and this dependency fix.
>
> 	* Makefile.am (TARGET_LIBOPCODES_CFILES): Add riscv files.
> 	* Makefile.in: Regenerate.
> 	* po/POTFILES.in: Regenerate.
>
> diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
> index e954cbe..737e8e3 100644
> --- a/opcodes/Makefile.am
> +++ b/opcodes/Makefile.am
> @@ -223,6 +223,8 @@ TARGET_LIBOPCODES_CFILES = \
>  	pj-opc.c \
>  	ppc-dis.c \
>  	ppc-opc.c \
> +	riscv-dis.c \
> +	riscv-opc.c \
>  	rl78-decode.c \
>  	rl78-dis.c \
>  	rx-decode.c \

Thanks!

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: RISC-V Fixes for 2.28 v4
  2016-12-19 18:01             ` Palmer Dabbelt
@ 2016-12-20  2:01               ` Alan Modra
  2016-12-20  2:01                 ` Palmer Dabbelt
  0 siblings, 1 reply; 57+ messages in thread
From: Alan Modra @ 2016-12-20  2:01 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: binutils, Andrew Waterman

On Mon, Dec 19, 2016 at 10:01:10AM -0800, Palmer Dabbelt wrote:
> If it's not too much work, it'd be great if you could commit these

Committed with a few more tidies, and this dependency fix.

	* Makefile.am (TARGET_LIBOPCODES_CFILES): Add riscv files.
	* Makefile.in: Regenerate.
	* po/POTFILES.in: Regenerate.

diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am
index e954cbe..737e8e3 100644
--- a/opcodes/Makefile.am
+++ b/opcodes/Makefile.am
@@ -223,6 +223,8 @@ TARGET_LIBOPCODES_CFILES = \
 	pj-opc.c \
 	ppc-dis.c \
 	ppc-opc.c \
+	riscv-dis.c \
+	riscv-opc.c \
 	rl78-decode.c \
 	rl78-dis.c \
 	rx-decode.c \

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 57+ messages in thread

end of thread, other threads:[~2016-12-20  2:01 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-15  4:28 RISC-V Fixes for 2.28 Palmer Dabbelt
2016-12-16 19:47 ` Palmer Dabbelt
2016-12-16 23:11   ` Alan Modra
2016-12-18  6:40     ` Palmer Dabbelt
2016-12-18  7:01   ` RISC-V Fixes for 2.28 v2 Palmer Dabbelt
2016-12-18  7:01     ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
2016-12-18  7:01     ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
2016-12-18  7:01     ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
2016-12-18  7:01     ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
2016-12-18  7:01     ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
2016-12-18  7:01     ` [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases Palmer Dabbelt
2016-12-18  7:01     ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
2016-12-18  7:01     ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
2016-12-18  7:01     ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
2016-12-19  0:26     ` RISC-V Fixes for 2.28 v2 Alan Modra
2016-12-19  4:27       ` RISC-V Fixes for 2.28 v3 Palmer Dabbelt
2016-12-19  4:27         ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
2016-12-19  4:27         ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
2016-12-19  4:27         ` [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases Palmer Dabbelt
2016-12-19  4:27         ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
2016-12-19  4:27         ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
2016-12-19  6:10           ` Alan Modra
2016-12-19  4:27         ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
2016-12-19  4:27         ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
2016-12-19  5:58           ` Alan Modra
2016-12-19  6:29             ` Palmer Dabbelt
2016-12-19  4:27         ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
2016-12-19  4:27         ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
2016-12-19  6:54         ` RISC-V Fixes for 2.28 v4 Palmer Dabbelt
2016-12-19  6:54           ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
2016-12-19  6:54           ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt
2016-12-19  6:54           ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
2016-12-19  6:54           ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
2016-12-19  6:54           ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
2016-12-19  6:54           ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
2016-12-19  6:54           ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
2016-12-19  6:54           ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
2016-12-19  8:46           ` RISC-V Fixes for 2.28 v4 Alan Modra
2016-12-19 18:01             ` Palmer Dabbelt
2016-12-20  2:01               ` Alan Modra
2016-12-20  2:01                 ` Palmer Dabbelt
2016-12-19  6:24       ` RISC-V Fixes for 2.28 v2 Cary Coutant
     [not found] <1481775826-6577-1-git-send-email-palmer@dabbelt.com>
2016-12-15  4:24 ` [PATCH 5/9] Re-work RISC-V gas flags: now we just support -mabi and -march Palmer Dabbelt
2016-12-15  4:24 ` [PATCH 7/9] Add canonical JALR assembly representation Palmer Dabbelt
2016-12-15  4:24 ` [PATCH 1/9] Improve a LD error message when linking elf32 and elf64 Palmer Dabbelt
2016-12-16 23:36   ` Mike Frysinger
2016-12-18  6:40     ` Palmer Dabbelt
2016-12-15  4:24 ` [PATCH 3/9] Rework RISC-V relocations Palmer Dabbelt
2016-12-16 23:39   ` Mike Frysinger
2016-12-18  6:40     ` Palmer Dabbelt
2016-12-15  4:24 ` [PATCH 4/9] Fix an integer overflow in relocation handling Palmer Dabbelt
2016-12-15  4:24 ` [PATCH 2/9] Formatting changes for RISC-V Palmer Dabbelt
2016-12-16 23:37   ` Mike Frysinger
2016-12-18  6:39     ` Palmer Dabbelt
2016-12-15  4:24 ` [PATCH 6/9] Don't define our own .p2align Palmer Dabbelt
2016-12-15  4:24 ` [PATCH 8/9] Fix disassembly of CSR instructions under -Mno-aliases Palmer Dabbelt
2016-12-15  4:24 ` [PATCH 9/9] Correct assembler mnemonic for aqrl AMOs Palmer Dabbelt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).