aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/config/tc-riscv.c15
-rw-r--r--gas/config/tc-riscv.h8
-rw-r--r--gas/testsuite/gas/riscv/la-variants.d3
3 files changed, 26 insertions, 0 deletions
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 10f1ac7..a46a6a4 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -59,6 +59,9 @@ struct riscv_cl_insn
fixS *fixp;
};
+/* The identifier of the assembler macro we are expanding, if any. */
+static int source_macro = -1;
+
/* All RISC-V CSR belong to one of these classes. */
enum riscv_csr_class
{
@@ -1749,6 +1752,7 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
address_expr, false, reloc_type);
ip->fixp->fx_tcbit = riscv_opts.relax;
+ ip->fixp->tc_fix_data.source_macro = source_macro;
}
}
@@ -2103,6 +2107,8 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
int rs2 = (ip->insn_opcode >> OP_SH_RS2) & OP_MASK_RS2;
int mask = ip->insn_mo->mask;
+ source_macro = mask;
+
switch (mask)
{
case M_LI:
@@ -2178,6 +2184,8 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
as_bad (_("internal: macro %s not implemented"), ip->insn_mo->name);
break;
}
+
+ source_macro = -1;
}
static const struct percent_op_match percent_op_utype[] =
@@ -4139,6 +4147,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
break;
case BFD_RELOC_RISCV_GOT_HI20:
+ /* R_RISCV_GOT_HI20 and the following R_RISCV_LO12_I are relaxable
+ only if it is created as a result of la or lga assembler macros. */
+ if (fixP->tc_fix_data.source_macro == M_LA
+ || fixP->tc_fix_data.source_macro == M_LGA)
+ relaxable = true;
+ break;
+
case BFD_RELOC_RISCV_ADD8:
case BFD_RELOC_RISCV_ADD16:
case BFD_RELOC_RISCV_ADD32:
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 9d2f05a..ff1c719 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -104,6 +104,14 @@ extern void riscv_md_end (void);
#define TC_FORCE_RELOCATION_LOCAL(FIX) 1
#define DIFF_EXPR_OK 1
+struct riscv_fix
+{
+ int source_macro;
+};
+
+#define TC_FIX_TYPE struct riscv_fix
+#define TC_INIT_FIX_DATA(FIX) (FIX)->tc_fix_data.source_macro = -1
+
extern void riscv_pop_insert (void);
#define md_pop_insert() riscv_pop_insert ()
diff --git a/gas/testsuite/gas/riscv/la-variants.d b/gas/testsuite/gas/riscv/la-variants.d
index b1d3169..e8ac09c 100644
--- a/gas/testsuite/gas/riscv/la-variants.d
+++ b/gas/testsuite/gas/riscv/la-variants.d
@@ -21,11 +21,13 @@ Disassembly of section .text:
[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*
[ ]+[0-9a-f]+:[ ]+00000617[ ]+auipc[ ]+a2,0x0
[ ]+[0-9a-f]+:[ ]+R_RISCV_GOT_HI20[ ]+a
+[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*
[ ]+[0-9a-f]+:[ ]+(00062603|00063603)[ ]+(lw|ld)[ ]+a2,0\(a2\).*
[ ]+[0-9a-f]+:[ ]+R_RISCV_PCREL_LO12_I[ ]+\.L0[ ]+
[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*
[ ]+[0-9a-f]+:[ ]+00000697[ ]+auipc[ ]+a3,0x0
[ ]+[0-9a-f]+:[ ]+R_RISCV_GOT_HI20[ ]+a
+[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*
[ ]+[0-9a-f]+:[ ]+(0006a683|0006b683)[ ]+(lw|ld)[ ]+a3,0\(a3\).*
[ ]+[0-9a-f]+:[ ]+R_RISCV_PCREL_LO12_I[ ]+\.L0[ ]+
[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*
@@ -37,6 +39,7 @@ Disassembly of section .text:
[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*
[ ]+[0-9a-f]+:[ ]+00000797[ ]+auipc[ ]+a5,0x0
[ ]+[0-9a-f]+:[ ]+R_RISCV_GOT_HI20[ ]+a
+[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*
[ ]+[0-9a-f]+:[ ]+(0007a783|0007b783)[ ]+(lw|ld)[ ]+a5,0\(a5\).*
[ ]+[0-9a-f]+:[ ]+R_RISCV_PCREL_LO12_I[ ]+\.L0[ ]+
[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*