[binutils-gdb] LoongArch: LA32R macros expand

liu zhensong liuzhensong@sourceware.org
Wed Dec 10 08:08:25 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f237e7c2d79ba4c1e4197221265cd2319aefcb07

commit f237e7c2d79ba4c1e4197221265cd2319aefcb07
Author: mengqinggang <mengqinggang@loongson.cn>
Date:   Mon Sep 8 17:01:46 2025 +0800

    LoongArch: LA32R macros expand
    
    Define a symbol .Lpcadd_hi* at R_LARCH_*_PCADD_HI20
    if the instruction expand from macro.
    Change the symbol of R_LARCH_PCADD_LO12 to .Lpcadd_hi*
    if the instruction expand from macro.

Diff:
---
 gas/config/tc-loongarch.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index fdfe5762184..a3e6fcb056c 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1382,6 +1382,18 @@ assember_macro_helper (const char *const args[], void *context_ptr)
   return ret;
 }
 
+static unsigned int pcadd_hi = 0;
+#define PCADD_HI_LABEL_NAME ".Lpcadd_hi"
+
+static char *
+loongarch_pcadd_hi_label_name (unsigned int n)
+{
+  static char symbol_name_build[24];
+  char *p = symbol_name_build;
+  sprintf (p, "%s%u", PCADD_HI_LABEL_NAME, n);
+  return symbol_name_build;
+}
+
 /* Accept instructions separated by ';'
  * assuming 'not starting with space and not ending with space' or pass in
  * empty c_str.  */
@@ -1420,6 +1432,33 @@ loongarch_assemble_INSNs (char *str, unsigned int expand_from_macro)
       loongarch_split_args_by_comma (str, the_one.arg_strs);
       get_loongarch_opcode (&the_one);
 
+      /* Make a new label .Lpcadd_hi* for pcadd_lo12.  */
+      if (expand_from_macro
+	  && the_one.reloc_num > 0
+	  && (the_one.reloc_info[0].type == BFD_RELOC_LARCH_PCADD_HI20
+	      || the_one.reloc_info[0].type == BFD_RELOC_LARCH_GOT_PCADD_HI20
+	      || the_one.reloc_info[0].type == BFD_RELOC_LARCH_TLS_IE_PCADD_HI20
+	      || the_one.reloc_info[0].type == BFD_RELOC_LARCH_TLS_LD_PCADD_HI20
+	      || the_one.reloc_info[0].type == BFD_RELOC_LARCH_TLS_GD_PCADD_HI20
+	      || the_one.reloc_info[0].type == BFD_RELOC_LARCH_TLS_DESC_PCADD_HI20))
+	{
+	  char *name = loongarch_pcadd_hi_label_name (pcadd_hi);
+	  local_symbol_make (name, now_seg, frag_now, frag_now_fix ());
+	}
+
+      /* Change symbol to .Lpcadd_hi*.  */
+      if (expand_from_macro
+	  && the_one.reloc_num > 0
+	  && the_one.reloc_info[0].type == BFD_RELOC_LARCH_PCADD_LO12)
+	{
+	  char *name = loongarch_pcadd_hi_label_name (pcadd_hi);
+	  symbolS *s = symbol_find (name);
+	  if (s == NULL)
+	    as_bad (_("no matched pcadd_hi label: %s"), name);
+	  the_one.reloc_info[0].value.X_add_symbol = s;
+	  pcadd_hi++;
+	}
+
       if (!the_one.all_match)
 	{
 	  char *ss = loongarch_cat_splited_strs (the_one.arg_strs);


More information about the Binutils-cvs mailing list