[v2] LoongArch: Deprecate $v[01], $fv[01] and $x names per spec

Message ID 20230628131311.3895731-1-i.swmail@xen0n.name
State Accepted
Headers
Series [v2] LoongArch: Deprecate $v[01], $fv[01] and $x names per spec |

Checks

Context Check Description
snail/binutils-gdb-check success Github commit url

Commit Message

WANG Xuerui June 28, 2023, 1:13 p.m. UTC
  From: WANG Xuerui <git@xen0n.name>

As outlined in the LoongArch ELF psABI spec [1], it is actually already
2 versions after the initial LoongArch support, and the $v[01] and
$fv[01] names should really get sunset by now.

In addition, the "$x" name for $r21 was never included in any released
version of the ABI spec, and such usages are all fixed to say just $r21
for every project I could think of that accepted a LoongArch port.
Plus, the upcoming LASX support makes use of registers named "$xrNN",
so having "$x" alongside would potentially create confusion for
developers.

Issue warnings for such usages per the deprecation procedure detailed
in the spec, so we can finally remove support in the next release cycle
after this.

[1]: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
---

v2:

- Rebased (I can't even remember v1 was when)
- Also deprecate $x (LASX will soon bring about $xrNN)
- Improve diagnostics

Hopefully this will make 2.41, to finally transition us away from old
2020 cruft...

 gas/config/tc-loongarch.c                     | 42 ++++++++++++++++---
 .../gas/loongarch/deprecated_reg_aliases.d    | 17 ++++++++
 .../gas/loongarch/deprecated_reg_aliases.l    |  7 ++++
 .../gas/loongarch/deprecated_reg_aliases.s    |  5 +++
 include/opcode/loongarch.h                    |  4 +-
 opcodes/loongarch-opc.c                       |  8 ++--
 6 files changed, 72 insertions(+), 11 deletions(-)
 create mode 100644 gas/testsuite/gas/loongarch/deprecated_reg_aliases.d
 create mode 100644 gas/testsuite/gas/loongarch/deprecated_reg_aliases.l
 create mode 100644 gas/testsuite/gas/loongarch/deprecated_reg_aliases.s
  

Patch

diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index d1c5ce287e4..5d6d6679120 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -221,8 +221,12 @@  md_parse_option (int c, const char *arg)
   return ret;
 }
 
+static const char *const *r_abi_names = NULL;
+static const char *const *f_abi_names = NULL;
 static struct htab *r_htab = NULL;
+static struct htab *r_deprecated_htab = NULL;
 static struct htab *f_htab = NULL;
+static struct htab *f_deprecated_htab = NULL;
 static struct htab *c_htab = NULL;
 static struct htab *cr_htab = NULL;
 static struct htab *v_htab = NULL;
@@ -266,7 +270,11 @@  loongarch_after_parse_args ()
   /* Init ilp32/lp64 registers names.  */
   if (!r_htab)
     r_htab = str_htab_create (), str_hash_insert (r_htab, "", 0, 0);
+  if (!r_deprecated_htab)
+    r_deprecated_htab = str_htab_create (),
+			str_hash_insert (r_deprecated_htab, "", 0, 0);
 
+  r_abi_names = loongarch_r_normal_name;
   for (i = 0; i < ARRAY_SIZE (loongarch_r_normal_name); i++)
     str_hash_insert (r_htab, loongarch_r_normal_name[i], (void *) (i + 1), 0);
 
@@ -281,7 +289,11 @@  loongarch_after_parse_args ()
     {
       if (!f_htab)
 	f_htab = str_htab_create (), str_hash_insert (f_htab, "", 0, 0);
+      if (!f_deprecated_htab)
+	f_deprecated_htab = str_htab_create (),
+			    str_hash_insert (f_deprecated_htab, "", 0, 0);
 
+      f_abi_names = loongarch_f_normal_name;
       for (i = 0; i < ARRAY_SIZE (loongarch_f_normal_name); i++)
 	str_hash_insert (f_htab, loongarch_f_normal_name[i], (void *) (i + 1),
 			 0);
@@ -318,22 +330,24 @@  loongarch_after_parse_args ()
   /* Init lp64 registers alias.  */
   if (LARCH_opts.ase_lp64)
     {
+      r_abi_names = loongarch_r_lp64_name;
       for (i = 0; i < ARRAY_SIZE (loongarch_r_lp64_name); i++)
 	str_hash_insert (r_htab, loongarch_r_lp64_name[i], (void *) (i + 1),
 			 0);
-      for (i = 0; i < ARRAY_SIZE (loongarch_r_lp64_name1); i++)
-	str_hash_insert (r_htab, loongarch_r_lp64_name1[i], (void *) (i + 1),
-			 0);
+      for (i = 0; i < ARRAY_SIZE (loongarch_r_lp64_name_deprecated); i++)
+	str_hash_insert (r_deprecated_htab, loongarch_r_lp64_name_deprecated[i],
+			 (void *) (i + 1), 0);
     }
 
   /* Init float-lp64 registers alias */
   if ((LARCH_opts.ase_sf || LARCH_opts.ase_df) && LARCH_opts.ase_lp64)
     {
+      f_abi_names = loongarch_f_lp64_name;
       for (i = 0; i < ARRAY_SIZE (loongarch_f_lp64_name); i++)
 	str_hash_insert (f_htab, loongarch_f_lp64_name[i],
 			 (void *) (i + 1), 0);
-      for (i = 0; i < ARRAY_SIZE (loongarch_f_lp64_name1); i++)
-	str_hash_insert (f_htab, loongarch_f_lp64_name1[i],
+      for (i = 0; i < ARRAY_SIZE (loongarch_f_lp64_name_deprecated); i++)
+	str_hash_insert (f_deprecated_htab, loongarch_f_lp64_name_deprecated[i],
 			 (void *) (i + 1), 0);
     }
 }
@@ -664,11 +678,29 @@  loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
       imm = (intptr_t) str_hash_find (r_htab, arg);
       ip->match_now = 0 < imm;
       ret = imm - 1;
+      if (ip->match_now)
+	break;
+      /* Handle potential usage of deprecated register aliases.  */
+      imm = (intptr_t) str_hash_find (r_deprecated_htab, arg);
+      ip->match_now = 0 < imm;
+      ret = imm - 1;
+      if (ip->match_now && !ip->macro_id)
+	as_warn (_("register alias %s is deprecated, use %s instead"),
+		 arg, r_abi_names[ret]);
       break;
     case 'f':
       imm = (intptr_t) str_hash_find (f_htab, arg);
       ip->match_now = 0 < imm;
       ret = imm - 1;
+      if (ip->match_now && !ip->macro_id)
+	break;
+      /* Handle potential usage of deprecated register aliases.  */
+      imm = (intptr_t) str_hash_find (f_deprecated_htab, arg);
+      ip->match_now = 0 < imm;
+      ret = imm - 1;
+      if (ip->match_now)
+	as_warn (_("register alias %s is deprecated, use %s instead"),
+		 arg, f_abi_names[ret]);
       break;
     case 'c':
       switch (esc_ch2)
diff --git a/gas/testsuite/gas/loongarch/deprecated_reg_aliases.d b/gas/testsuite/gas/loongarch/deprecated_reg_aliases.d
new file mode 100644
index 00000000000..c2cb6f85ee5
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/deprecated_reg_aliases.d
@@ -0,0 +1,17 @@ 
+#name: Deprecated register aliases
+#as-new:
+#objdump: -d
+#warning_output: deprecated_reg_aliases.l
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0000000000000000 <foo>:
+[ 	]+0:[ 	]+14acf125[ 	]+lu12i\.w[ 	]+\$a1, 354185\(0x56789\)
+[ 	]+4:[ 	]+038048a5[ 	]+ori[ 	]+\$a1, \$a1, 0x12
+[ 	]+8:[ 	]+16024685[ 	]+lu32i\.d[ 	]+\$a1, 4660\(0x1234\)
+[ 	]+c:[ 	]+08200420[ 	]+fmadd\.d[ 	]+\$fa0, \$fa1, \$fa1, \$fa0
+[ 	]+10:[ 	]+380c16a4[ 	]+ldx\.d[ 	]+\$a0, \$r21, \$a1
+[ 	]+14:[ 	]+4c000020[ 	]+jirl[ 	]+\$zero, \$ra, 0
diff --git a/gas/testsuite/gas/loongarch/deprecated_reg_aliases.l b/gas/testsuite/gas/loongarch/deprecated_reg_aliases.l
new file mode 100644
index 00000000000..b82c209e541
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/deprecated_reg_aliases.l
@@ -0,0 +1,7 @@ 
+.*Assembler messages:
+.*:2: Warning: register alias \$v1 is deprecated, use \$a1 instead
+.*:3: Warning: register alias \$fv0 is deprecated, use \$fa0 instead
+.*:3: Warning: register alias \$fv1 is deprecated, use \$fa1 instead
+.*:3: Warning: register alias \$fv1 is deprecated, use \$fa1 instead
+.*:4: Warning: register alias \$v0 is deprecated, use \$a0 instead
+.*:4: Warning: register alias \$x is deprecated, use \$r21 instead
diff --git a/gas/testsuite/gas/loongarch/deprecated_reg_aliases.s b/gas/testsuite/gas/loongarch/deprecated_reg_aliases.s
new file mode 100644
index 00000000000..7848346e6ae
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/deprecated_reg_aliases.s
@@ -0,0 +1,5 @@ 
+foo:
+    li.d $v1, 0x123456789012
+    fmadd.d $fv0, $fv1, $fv1, $fa0
+    ldx.d $v0, $x, $a1
+    ret
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index 004bb6561ef..de62b1693a0 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -181,10 +181,10 @@  dec2 : [1-9][0-9]?
 
   extern const char *const loongarch_r_normal_name[32];
   extern const char *const loongarch_r_lp64_name[32];
-  extern const char *const loongarch_r_lp64_name1[32];
+  extern const char *const loongarch_r_lp64_name_deprecated[32];
   extern const char *const loongarch_f_normal_name[32];
   extern const char *const loongarch_f_lp64_name[32];
-  extern const char *const loongarch_f_lp64_name1[32];
+  extern const char *const loongarch_f_lp64_name_deprecated[32];
   extern const char *const loongarch_c_normal_name[8];
   extern const char *const loongarch_cr_normal_name[4];
   extern const char *const loongarch_v_normal_name[32];
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 573b691c1fd..e3dbe1c1c10 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -45,14 +45,14 @@  const char *const loongarch_r_lp64_name[32] =
 {
   "$zero", "$ra", "$tp", "$sp", "$a0", "$a1", "$a2", "$a3",
   "$a4",   "$a5", "$a6", "$a7", "$t0", "$t1", "$t2", "$t3",
-  "$t4",   "$t5", "$t6", "$t7", "$t8", "$x",  "$fp", "$s0",
+  "$t4",   "$t5", "$t6", "$t7", "$t8", "$r21","$fp", "$s0",
   "$s1",   "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", "$s8",
 };
 
-const char *const loongarch_r_lp64_name1[32] =
+const char *const loongarch_r_lp64_name_deprecated[32] =
 {
   "", "", "", "", "$v0", "$v1", "", "", "", "", "", "", "", "", "", "",
-  "", "", "", "", "",    "",    "", "", "", "", "", "", "", "", "", "",
+  "", "", "", "", "",    "$x",  "", "", "", "", "", "", "", "", "", "",
 };
 
 const char *const loongarch_f_normal_name[32] =
@@ -71,7 +71,7 @@  const char *const loongarch_f_lp64_name[32] =
   "$fs0", "$fs1", "$fs2",  "$fs3",  "$fs4",  "$fs5",  "$fs6",  "$fs7",
 };
 
-const char *const loongarch_f_lp64_name1[32] =
+const char *const loongarch_f_lp64_name_deprecated[32] =
 {
   "$fv0", "$fv1", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
   "",     "",     "", "", "", "", "", "", "", "", "", "", "", "", "", "",