RISC-V/GAS: Support more relocs against constant addresses
authorAndrew Waterman <andrew@sifive.com>
Thu, 22 Dec 2016 02:05:28 +0000 (18:05 -0800)
committerPalmer Dabbelt <palmer@dabbelt.com>
Mon, 9 Jan 2017 17:20:05 +0000 (09:20 -0800)
Previously, some pseudoinstructions like "call" only accepted
symbolic addresses and rejected constant addresses with an
esoteric internal error.  This patch enables them by deferring
application of constant relocations to md_apply_fix, rather than
eagerly applying them during instruction assembly.

gas/ChangeLog

2017-01-09  Andrew Waterman <andrew@sifive.com>

* config/tc-riscv.c (append_insn): Don't eagerly apply relocations
against constants.
(md_apply_fix): Mark relocations against constants as "done."

gas/ChangeLog
gas/config/tc-riscv.c

index 4de9cf7eff404649238a45c26266fb2a1e5b7d9d..0fab5fba7741ab006ce73a828d9598df2dc53f23 100644 (file)
@@ -4,6 +4,12 @@
        against constants.
        (md_apply_fix): Mark relocations against constants as "done."
 
+2017-01-09  Andrew Waterman <andrew@sifive.com>
+
+       * config/tc-riscv.c (append_insn): Don't eagerly apply relocations
+       against constants.
+       (md_apply_fix): Mark relocations against constants as "done."
+
 2017-01-09  Palmer Dabbelt <palmer@dabbelt.com>
            Kito Cheng <kito.cheng@gmail.com>
 
index 3f09101108e21fba07c44586214e22994a5c26b2..6bbaa4b101051a33f96eb966a966bb5f57578d24 100644 (file)
@@ -688,9 +688,6 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
                            address_expr->X_add_number);
          return;
        }
-      else if (address_expr->X_op == O_constant)
-       ip->insn_opcode |= riscv_apply_const_reloc (reloc_type,
-                                                   address_expr->X_add_number);
       else
        {
          howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
@@ -1861,6 +1858,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_RISCV_LO12_S:
       bfd_putl32 (riscv_apply_const_reloc (fixP->fx_r_type, *valP)
                  | bfd_getl32 (buf), buf);
+      if (fixP->fx_addsy == NULL)
+       fixP->fx_done = TRUE;
       relaxable = TRUE;
       break;