[v1] LoongArch: Warn about right shifts of negative numbers

Message ID 20250403023743.3918047-1-cailulu@loongson.cn
State New
Headers
Series [v1] LoongArch: Warn about right shifts of negative numbers |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Lulu Cai April 3, 2025, 2:37 a.m. UTC
  The GNU Assembler User Guide says that the right shift operator ">>"
in an expression is the same as the C operator.

On LoongArch the assembler directives and instructions do not treat
negative numbers ">>" the same way. The directives treats negative
numbers ">>" as logical right shifts while the instructions treats them
as arithmetic right shifts.

The right shift of negative numbers in the instructions may be changed
from an arithmetic right shift to a logical right shift in the future,
and a warning is issued for this.
---
 gas/config/loongarch-parse.y                  |  3 ++
 gas/testsuite/gas/loongarch/loongarch.exp     |  1 +
 .../gas/loongarch/negative_right_shift.d      | 40 +++++++++++++++++++
 .../gas/loongarch/negative_right_shift.l      | 13 ++++++
 .../gas/loongarch/negative_right_shift.s      | 32 +++++++++++++++
 5 files changed, 89 insertions(+)
 create mode 100644 gas/testsuite/gas/loongarch/negative_right_shift.d
 create mode 100644 gas/testsuite/gas/loongarch/negative_right_shift.l
 create mode 100644 gas/testsuite/gas/loongarch/negative_right_shift.s
  

Patch

diff --git a/gas/config/loongarch-parse.y b/gas/config/loongarch-parse.y
index ac35deee1de..97055fe42c3 100644
--- a/gas/config/loongarch-parse.y
+++ b/gas/config/loongarch-parse.y
@@ -225,6 +225,9 @@  emit_bin (int op)
 	  opr1 = opr1 << opr2;
 	  break;
 	case RIGHT_OP:
+	  if (opr1 < 0)
+	    as_warn(_("Right shift of negative numbers may be changed "
+		  "from arithmetic right shift to logical right shift!"));
 	  /* Algorithm right shift.  */
 	  opr1 = (offsetT)opr1 >> (offsetT)opr2;
 	  break;
diff --git a/gas/testsuite/gas/loongarch/loongarch.exp b/gas/testsuite/gas/loongarch/loongarch.exp
index 87595b91cce..0e836f7f217 100644
--- a/gas/testsuite/gas/loongarch/loongarch.exp
+++ b/gas/testsuite/gas/loongarch/loongarch.exp
@@ -36,5 +36,6 @@  if [istarget loongarch*-*-*] {
   if [istarget loongarch64-*-*] {
     run_list_test "illegal-operand"
     run_list_test "pseudo_op_option_fail"
+    run_list_test "negative_right_shift"
   }
 }
diff --git a/gas/testsuite/gas/loongarch/negative_right_shift.d b/gas/testsuite/gas/loongarch/negative_right_shift.d
new file mode 100644
index 00000000000..4237710c2b3
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/negative_right_shift.d
@@ -0,0 +1,40 @@ 
+#as:
+#objdump: -d
+#skip: loongarch32-*-*
+#warning_output: negative_right_shift.l
+
+.*:     file format .*
+
+
+Disassembly of section \.text:
+
+0+ <directives>:
+   0:	03400000 	nop
+   4:	00000001 	\.word		0x00000001
+   8:	00000001 	\.word		0x00000001
+
+0+c <insns>:
+   c:	02bff9ac 	addi.w      	\$t0, \$t1, -2
+  10:	02fff9ac 	addi.d      	\$t0, \$t1, -2
+  14:	13fff9ac 	addu16i.d   	\$t0, \$t1, -2
+  18:	15ffffcc 	lu12i.w     	\$t0, -2
+  1c:	17ffffcc 	lu32i.d     	\$t0, -2
+  20:	033ff9ac 	lu52i.d     	\$t0, \$t1, -2
+  24:	023ff9ac 	slti        	\$t0, \$t1, -2
+  28:	027ff9ac 	sltui       	\$t0, \$t1, -2
+  2c:	19ffffcc 	pcaddi      	\$t0, -2
+  30:	1dffffcc 	pcaddu12i   	\$t0, -2
+  34:	1fffffcc 	pcaddu18i   	\$t0, -2
+  38:	1bffffcc 	pcalau12i   	\$t0, -2
+  3c:	02bffdac 	addi.w      	\$t0, \$t1, -1
+  40:	02fffdac 	addi.d      	\$t0, \$t1, -1
+  44:	13fffdac 	addu16i.d   	\$t0, \$t1, -1
+  48:	15ffffec 	lu12i.w     	\$t0, -1
+  4c:	17ffffec 	lu32i.d     	\$t0, -1
+  50:	033ffdac 	lu52i.d     	\$t0, \$t1, -1
+  54:	023ffdac 	slti        	\$t0, \$t1, -1
+  58:	027ffdac 	sltui       	\$t0, \$t1, -1
+  5c:	19ffffec 	pcaddi      	\$t0, -1
+  60:	1dffffec 	pcaddu12i   	\$t0, -1
+  64:	1fffffec 	pcaddu18i   	\$t0, -1
+  68:	1bffffec 	pcalau12i   	\$t0, -1
diff --git a/gas/testsuite/gas/loongarch/negative_right_shift.l b/gas/testsuite/gas/loongarch/negative_right_shift.l
new file mode 100644
index 00000000000..6edb2a5ebf8
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/negative_right_shift.l
@@ -0,0 +1,13 @@ 
+.*: Assembler messages:
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
+.*: Warning: Right shift of negative numbers may be changed from arithmetic right shift to logical right shift!
diff --git a/gas/testsuite/gas/loongarch/negative_right_shift.s b/gas/testsuite/gas/loongarch/negative_right_shift.s
new file mode 100644
index 00000000000..c6a8a1e7c6e
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/negative_right_shift.s
@@ -0,0 +1,32 @@ 
+directives:
+.align	  -1>>62
+.word	  -1>>63
+.4byte	  -1>>63
+
+insns:
+addi.w	  $t0, $t1, -1<<1
+addi.d	  $t0, $t1, -1<<1
+addu16i.d $t0, $t1, -1<<1
+lu12i.w	  $t0, -1<<1
+lu32i.d	  $t0, -1<<1
+lu52i.d	  $t0, $t1, -1<<1
+slti	  $t0, $t1, -1<<1
+sltui	  $t0, $t1, -1<<1
+pcaddi	  $t0, -1<<1
+pcaddu12i $t0, -1<<1
+pcaddu18i $t0, -1<<1
+pcalau12i $t0, -1<<1
+
+# warn
+addi.w	  $t0, $t1, -1>>63
+addi.d	  $t0, $t1, -1>>63
+addu16i.d $t0, $t1, -1>>63
+lu12i.w	  $t0, -1>>63
+lu32i.d	  $t0, -1>>63
+lu52i.d	  $t0, $t1, -1>>63
+slti	  $t0, $t1, -1>>63
+sltui	  $t0, $t1, -1>>63
+pcaddi	  $t0, -1>>63
+pcaddu12i $t0, -1>>63
+pcaddu18i $t0, -1>>63
+pcalau12i $t0, -1>>63