@@ -1956,6 +1956,9 @@ riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type, bfd_vma value)
19561956 case BFD_RELOC_RISCV_LO12_I :
19571957 return ENCODE_ITYPE_IMM (value );
19581958
1959+ case BFD_RELOC_RISCV_LPAD :
1960+ return ENCODE_UTYPE_IMM (value << RISCV_IMM_BITS );
1961+
19591962 default :
19601963 abort ();
19611964 }
@@ -3678,6 +3681,16 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
36783681 * imm_reloc = BFD_RELOC_RISCV_HI20 ;
36793682 imm_expr -> X_add_number <<= RISCV_IMM_BITS ;
36803683 }
3684+ {
3685+ bool is_lpad = strcmp (str , "lpad" ) == 0 ;
3686+ if (is_lpad )
3687+ {
3688+ /* Always insert a lpad relocation for lpad instruction. */
3689+ * imm_reloc = BFD_RELOC_RISCV_LPAD ;
3690+ /* And recover the immediate format to unshift value. */
3691+ imm_expr -> X_add_number >>= RISCV_IMM_BITS ;
3692+ }
3693+ }
36813694 asarg = expr_parse_end ;
36823695 continue ;
36833696
@@ -4671,6 +4684,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
46714684
46724685 switch (fixP -> fx_r_type )
46734686 {
4687+ case BFD_RELOC_RISCV_LPAD :
4688+ bfd_putl32 (riscv_apply_const_reloc (fixP -> fx_r_type , * valP )
4689+ | bfd_getl32 (buf ), buf );
4690+ fixP -> fx_done = false;
4691+ fixP -> fx_addnumber = 0 ;
4692+ fixP -> fx_offset = 0 ;
4693+ relaxable = true;
4694+ break ;
46744695 case BFD_RELOC_RISCV_HI20 :
46754696 case BFD_RELOC_RISCV_LO12_I :
46764697 case BFD_RELOC_RISCV_LO12_S :
@@ -4965,8 +4986,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
49654986 if (fixP -> fx_subsy != NULL )
49664987 as_bad_subtract (fixP );
49674988
4968- /* Add an R_RISCV_RELAX reloc if the reloc is relaxable. */
4969- if (relaxable && fixP -> fx_tcbit && fixP -> fx_addsy != NULL )
4989+ /* Add an R_RISCV_RELAX reloc if the reloc is relaxable,
4990+ and we need that for R_RISCV_LPAD as well. */
4991+ if (relaxable && fixP -> fx_tcbit
4992+ && (fixP -> fx_addsy != NULL
4993+ || (fixP -> fx_r_type == BFD_RELOC_RISCV_LPAD )))
49704994 {
49714995 fixP -> fx_next = xmemdup (fixP , sizeof (* fixP ), sizeof (* fixP ));
49724996 fixP -> fx_next -> fx_addsy = fixP -> fx_next -> fx_subsy = NULL ;
0 commit comments